mu-maildir: refactor some duplicate code
mu-flags & mu-maildir were having some duplicate code; refactor it into mu-message-file.{cc,hh}
This commit is contained in:
@ -247,123 +247,6 @@ Mu::maildir_clear_links(const std::string& path)
|
||||
return Ok();
|
||||
}
|
||||
|
||||
Result<std::string>
|
||||
Mu::maildir_from_path(const std::string& path, const std::string& root)
|
||||
{
|
||||
const auto pos = path.find(root);
|
||||
if (pos != 0 || path[root.length()] != '/')
|
||||
return Err(Error{Error::Code::InvalidArgument,
|
||||
"root '%s' is not a root for path '%s'",
|
||||
root.c_str(), path.c_str()});
|
||||
|
||||
auto mdir{path.substr(root.length())};
|
||||
auto slash{mdir.rfind('/')};
|
||||
|
||||
if (G_UNLIKELY(slash == std::string::npos) || slash < 4)
|
||||
return Err(Error{Error::Code::InvalidArgument,
|
||||
"invalid path: %s", path.c_str()});
|
||||
mdir.erase(slash);
|
||||
auto subdir = mdir.data() + slash - 4;
|
||||
if (G_UNLIKELY(strncmp(subdir, "/cur", 4) != 0 && strncmp(subdir, "/new", 4)))
|
||||
return Err(Error::Code::InvalidArgument,
|
||||
"cannot find '/new' or '/cur' - invalid path: %s",
|
||||
path.c_str());
|
||||
|
||||
if (mdir.length() == 4)
|
||||
return "/";
|
||||
|
||||
mdir.erase(mdir.length() - 4);
|
||||
|
||||
return Ok(std::move(mdir));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The file-components, ie.
|
||||
* 1631819685.fb7b279bbb0a7b66.evergrey:2,RS
|
||||
* => {
|
||||
* "1631819685.fb7b279bbb0a7b66.evergrey",
|
||||
* ':',
|
||||
* "2,",
|
||||
* "RS"
|
||||
* }
|
||||
*/
|
||||
struct FileParts {
|
||||
std::string base;
|
||||
char separator;
|
||||
std::string flags_suffix;
|
||||
};
|
||||
|
||||
static FileParts
|
||||
message_file_parts(const std::string& file)
|
||||
{
|
||||
const auto pos{file.find_last_of(":!;")};
|
||||
|
||||
/* no suffix at all? */
|
||||
if (pos == std::string::npos ||
|
||||
pos > file.length() - 3 ||
|
||||
file[pos + 1] != '2' ||
|
||||
file[pos + 2] != ',')
|
||||
return FileParts{ file, ':', {}};
|
||||
|
||||
return FileParts {
|
||||
file.substr(0, pos),
|
||||
file[pos],
|
||||
file.substr(pos + 3)
|
||||
};
|
||||
}
|
||||
|
||||
struct DirFile {
|
||||
std::string dir;
|
||||
std::string file;
|
||||
bool is_new;
|
||||
};
|
||||
|
||||
static Result<DirFile>
|
||||
base_message_dir_file(const std::string& path)
|
||||
{
|
||||
constexpr auto newdir{ G_DIR_SEPARATOR_S "new"};
|
||||
|
||||
char *dirname{g_path_get_dirname(path.c_str())};
|
||||
bool is_new{!!g_str_has_suffix(dirname, newdir)};
|
||||
|
||||
std::string mdir{dirname, ::strlen(dirname) - 4};
|
||||
g_free(dirname);
|
||||
|
||||
char *basename{g_path_get_basename(path.c_str())};
|
||||
std::string bname{basename};
|
||||
g_free(basename);
|
||||
|
||||
return Ok(DirFile{std::move(mdir), std::move(bname), is_new});
|
||||
}
|
||||
|
||||
// refactor: we have the same code in mu-flags.cc
|
||||
|
||||
Mu::Result<Mu::Flags>
|
||||
Mu::maildir_flags_from_path(const std::string& path)
|
||||
{ /*
|
||||
* this gets us the source maildir filesystem path, the directory
|
||||
* in which new/ & cur/ lives, and the source file
|
||||
*/
|
||||
auto dirfile{base_message_dir_file(path)};
|
||||
if (!dirfile)
|
||||
return Err(std::move(dirfile.error()));
|
||||
|
||||
/* a message under new/ is just.. New. Filename is not considered */
|
||||
if (dirfile->is_new)
|
||||
return Ok(Flags::New);
|
||||
|
||||
/* it's cur/ message, so parse the file name */
|
||||
const auto parts{message_file_parts(dirfile->file)};
|
||||
auto flags{flags_from_absolute_expr(parts.flags_suffix,
|
||||
true/*ignore invalid*/)};
|
||||
if (!flags)
|
||||
return Err(Error{Error::Code::InvalidArgument,
|
||||
"invalid flags ('%s')", parts.flags_suffix.c_str()});
|
||||
else
|
||||
return Ok(std::move(flags.value()));
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
get_file_size(const std::string& path)
|
||||
|
||||
Reference in New Issue
Block a user