lib+guile: use Mu::Option, not std::optional

We need the extensions, and/or let's use _one_ optional implementation everywhere.
This commit is contained in:
Dirk-Jan C. Binnema 2022-03-28 08:58:04 +03:00
parent 5a28cdfba4
commit 27ebfb3b3c
11 changed files with 94 additions and 90 deletions

View File

@ -213,7 +213,7 @@ SCM_DEFINE(get_field,
#undef FUNC_NAME #undef FUNC_NAME
static SCM static SCM
contacts_to_list(MuMsg *msg, std::optional<Field::Id> field_id) contacts_to_list(MuMsg *msg, Option<Field::Id> field_id)
{ {
SCM list{SCM_EOL}; SCM list{SCM_EOL};
@ -252,7 +252,7 @@ SCM_DEFINE(get_contacts,
if (CONTACT_TYPE == SCM_BOOL_F) if (CONTACT_TYPE == SCM_BOOL_F)
return SCM_UNSPECIFIED; /* nothing to do */ return SCM_UNSPECIFIED; /* nothing to do */
std::optional<Field::Id> field_id; Option<Field::Id> field_id;
if (CONTACT_TYPE == SCM_BOOL_T) if (CONTACT_TYPE == SCM_BOOL_T)
field_id = {}; /* get all */ field_id = {}; /* get all */
else { else {

View File

@ -24,7 +24,8 @@
#include <optional> #include <optional>
#include <string_view> #include <string_view>
#include <array> #include <array>
#include "utils/mu-utils.hh" #include <utils/mu-utils.hh>
#include <utils/mu-option.hh>
namespace Mu { namespace Mu {
@ -146,16 +147,16 @@ constexpr void flag_infos_for_each(Func&& func)
* *
* @param flag a singular flag * @param flag a singular flag
* *
* @return the MessageFlagInfo, or std::nullopt in case of error. * @return the MessageFlagInfo, or Nothing in case of error.
*/ */
constexpr const std::optional<MessageFlagInfo> constexpr const Option<MessageFlagInfo>
flag_info(Flags flag) flag_info(Flags flag)
{ {
constexpr auto upper = static_cast<unsigned>(Flags::_final_); constexpr auto upper = static_cast<unsigned>(Flags::_final_);
const auto val = static_cast<unsigned>(flag); const auto val = static_cast<unsigned>(flag);
if (__builtin_popcount(val) != 1 || val >= upper) if (__builtin_popcount(val) != 1 || val >= upper)
return std::nullopt; return Nothing;
return AllMessageFlagInfos[static_cast<unsigned>(__builtin_ctz(val))]; return AllMessageFlagInfos[static_cast<unsigned>(__builtin_ctz(val))];
} }
@ -167,14 +168,14 @@ flag_info(Flags flag)
* *
* @return the MessageFlagInfo * @return the MessageFlagInfo
*/ */
constexpr const std::optional<MessageFlagInfo> constexpr const Option<MessageFlagInfo>
flag_info(char shortcut) flag_info(char shortcut)
{ {
for (auto&& info : AllMessageFlagInfos) for (auto&& info : AllMessageFlagInfos)
if (info.shortcut == shortcut) if (info.shortcut == shortcut)
return info; return info;
return std::nullopt; return Nothing;
} }
/** /**
@ -184,14 +185,14 @@ flag_info(char shortcut)
* *
* @return the MessageFlagInfo * @return the MessageFlagInfo
*/ */
constexpr const std::optional<MessageFlagInfo> constexpr const Option<MessageFlagInfo>
flag_info(std::string_view name) flag_info(std::string_view name)
{ {
for (auto&& info : AllMessageFlagInfos) for (auto&& info : AllMessageFlagInfos)
if (info.name == name) if (info.name == name)
return info; return info;
return std::nullopt; return Nothing;
} }
/** /**
@ -209,7 +210,7 @@ flag_info(std::string_view name)
* *
* @return the (OR'ed) flags or Flags::None * @return the (OR'ed) flags or Flags::None
*/ */
constexpr std::optional<Flags> constexpr Option<Flags>
flags_from_absolute_expr(std::string_view expr, bool ignore_invalid = false) flags_from_absolute_expr(std::string_view expr, bool ignore_invalid = false)
{ {
Flags flags{Flags::None}; Flags flags{Flags::None};
@ -217,7 +218,7 @@ flags_from_absolute_expr(std::string_view expr, bool ignore_invalid = false)
for (auto&& kar : expr) { for (auto&& kar : expr) {
if (const auto& info{flag_info(kar)}; !info) { if (const auto& info{flag_info(kar)}; !info) {
if (!ignore_invalid) if (!ignore_invalid)
return std::nullopt; return Nothing;
} else } else
flags |= info->flag; flags |= info->flag;
} }
@ -242,24 +243,24 @@ flags_from_absolute_expr(std::string_view expr, bool ignore_invalid = false)
* *
* @return new flags, or nullopt in case of error * @return new flags, or nullopt in case of error
*/ */
constexpr std::optional<Flags> constexpr Option<Flags>
flags_from_delta_expr(std::string_view expr, Flags flags, flags_from_delta_expr(std::string_view expr, Flags flags,
bool ignore_invalid = false) bool ignore_invalid = false)
{ {
if (expr.size() % 2 != 0) if (expr.size() % 2 != 0)
return std::nullopt; return Nothing;
for (auto u = 0U; u != expr.size(); u += 2) { for (auto u = 0U; u != expr.size(); u += 2) {
if (const auto& info{flag_info(expr[u + 1])}; !info) { if (const auto& info{flag_info(expr[u + 1])}; !info) {
if (!ignore_invalid) if (!ignore_invalid)
return std::nullopt; return Nothing;
} else { } else {
switch (expr[u]) { switch (expr[u]) {
case '+': flags |= info->flag; break; case '+': flags |= info->flag; break;
case '-': flags &= ~info->flag; break; case '-': flags &= ~info->flag; break;
default: default:
if (!ignore_invalid) if (!ignore_invalid)
return std::nullopt; return Nothing;
break; break;
} }
} }
@ -274,14 +275,14 @@ flags_from_delta_expr(std::string_view expr, Flags flags,
* @param expr a flag expression, either 'delta' or 'absolute' * @param expr a flag expression, either 'delta' or 'absolute'
* @param flags optional: existing flags or none. Required for delta. * @param flags optional: existing flags or none. Required for delta.
* *
* @return either messages flags or std::nullopt in case of error. * @return either messages flags or Nothing in case of error.
*/ */
constexpr std::optional<Flags> constexpr Option<Flags>
flags_from_expr(std::string_view expr, flags_from_expr(std::string_view expr,
std::optional<Flags> flags = std::nullopt) Option<Flags> flags = Nothing)
{ {
if (expr.empty()) if (expr.empty())
return std::nullopt; return Nothing;
if (expr[0] == '+' || expr[0] == '-') if (expr[0] == '+' || expr[0] == '-')
return flags_from_delta_expr( return flags_from_delta_expr(

View File

@ -636,7 +636,7 @@ get_all_contacts(MuMsg *self)
} }
Mu::Contacts Mu::Contacts
Mu::mu_msg_get_contacts(MuMsg *self, std::optional<Field::Id> field_id) Mu::mu_msg_get_contacts(MuMsg *self, Option<Field::Id> field_id)
{ {
typedef const char*(*AddressFunc)(MuMsg*); typedef const char*(*AddressFunc)(MuMsg*);
using AddressInfo = std::pair<GMimeAddressType, AddressFunc>; using AddressInfo = std::pair<GMimeAddressType, AddressFunc>;

View File

@ -446,7 +446,7 @@ bool mu_msg_move_to_maildir(MuMsg* msg,
* @return a sequence * @return a sequence
*/ */
Mu::Contacts mu_msg_get_contacts (MuMsg *self, Mu::Contacts mu_msg_get_contacts (MuMsg *self,
std::optional<Field::Id> field_id={}); Option<Field::Id> field_id={});
/** /**
* create a 'display contact' from an email header To/Cc/Bcc/From-type address * create a 'display contact' from an email header To/Cc/Bcc/From-type address
* ie., turn * ie., turn

View File

@ -42,23 +42,23 @@ struct Query::Private {
// bool calculate_threads (Xapian::Enquire& enq, size maxnum); // bool calculate_threads (Xapian::Enquire& enq, size maxnum);
Xapian::Enquire make_enquire(const std::string& expr, Xapian::Enquire make_enquire(const std::string& expr,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags) const; QueryFlags qflags) const;
Xapian::Enquire make_related_enquire(const StringSet& thread_ids, Xapian::Enquire make_related_enquire(const StringSet& thread_ids,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags) const; QueryFlags qflags) const;
Option<QueryResults> run_threaded(QueryResults&& qres, Xapian::Enquire& enq, Option<QueryResults> run_threaded(QueryResults&& qres, Xapian::Enquire& enq,
QueryFlags qflags, size_t max_size) const; QueryFlags qflags, size_t max_size) const;
Option<QueryResults> run_singular(const std::string& expr, Option<QueryResults> run_singular(const std::string& expr,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags, size_t maxnum) const; QueryFlags qflags, size_t maxnum) const;
Option<QueryResults> run_related(const std::string& expr, Option<QueryResults> run_related(const std::string& expr,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags, size_t maxnum) const; QueryFlags qflags, size_t maxnum) const;
Option<QueryResults> run(const std::string& expr, Option<QueryResults> run(const std::string& expr,
std::optional<Field::Id> sortfield_id, QueryFlags qflags, Option<Field::Id> sortfield_id, QueryFlags qflags,
size_t maxnum) const; size_t maxnum) const;
size_t store_size() const { return store_.database().get_doccount(); } size_t store_size() const { return store_.database().get_doccount(); }
@ -84,7 +84,7 @@ sort_enquire(Xapian::Enquire& enq, Field::Id sortfield_id, QueryFlags qflags)
Xapian::Enquire Xapian::Enquire
Query::Private::make_enquire(const std::string& expr, Query::Private::make_enquire(const std::string& expr,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags) const QueryFlags qflags) const
{ {
Xapian::Enquire enq{store_.database()}; Xapian::Enquire enq{store_.database()};
@ -108,7 +108,7 @@ Query::Private::make_enquire(const std::string& expr,
Xapian::Enquire Xapian::Enquire
Query::Private::make_related_enquire(const StringSet& thread_ids, Query::Private::make_related_enquire(const StringSet& thread_ids,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags) const QueryFlags qflags) const
{ {
Xapian::Enquire enq{store_.database()}; Xapian::Enquire enq{store_.database()};
@ -156,7 +156,7 @@ Query::Private::run_threaded(QueryResults&& qres, Xapian::Enquire& enq, QueryFla
Option<QueryResults> Option<QueryResults>
Query::Private::run_singular(const std::string& expr, Query::Private::run_singular(const std::string& expr,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags, size_t maxnum) const QueryFlags qflags, size_t maxnum) const
{ {
// i.e. a query _without_ related messages, but still possibly // i.e. a query _without_ related messages, but still possibly
@ -197,7 +197,7 @@ opt_string(const Xapian::Document& doc, Field::Id id) noexcept
Option<QueryResults> Option<QueryResults>
Query::Private::run_related(const std::string& expr, Query::Private::run_related(const std::string& expr,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags qflags, size_t maxnum) const QueryFlags qflags, size_t maxnum) const
{ {
// i.e. a query _with_ related messages and possibly with threading. // i.e. a query _with_ related messages and possibly with threading.
@ -231,7 +231,7 @@ Query::Private::run_related(const std::string& expr,
// is unlimited and the sorting happens during threading. // is unlimited and the sorting happens during threading.
auto r_enq = std::invoke([&]{ auto r_enq = std::invoke([&]{
if (threading) if (threading)
return make_related_enquire(minfo.thread_ids, std::nullopt, qflags); return make_related_enquire(minfo.thread_ids, Nothing, qflags);
else else
return make_related_enquire(minfo.thread_ids, sortfield_id, qflags); return make_related_enquire(minfo.thread_ids, sortfield_id, qflags);
}); });
@ -244,7 +244,7 @@ Query::Private::run_related(const std::string& expr,
Option<QueryResults> Option<QueryResults>
Query::Private::run(const std::string& expr, Query::Private::run(const std::string& expr,
std::optional<Field::Id> sortfield_id, QueryFlags qflags, Option<Field::Id> sortfield_id, QueryFlags qflags,
size_t maxnum) const size_t maxnum) const
{ {
const auto eff_maxnum{maxnum == 0 ? store_size() : maxnum}; const auto eff_maxnum{maxnum == 0 ? store_size() : maxnum};
@ -259,7 +259,7 @@ Query::Private::run(const std::string& expr,
} }
Option<QueryResults> Option<QueryResults>
Query::run(const std::string& expr, std::optional<Field::Id> sortfield_id, Query::run(const std::string& expr, Option<Field::Id> sortfield_id,
QueryFlags qflags, size_t maxnum) const QueryFlags qflags, size_t maxnum) const
try { try {
// some flags are for internal use only. // some flags are for internal use only.

View File

@ -21,12 +21,12 @@
#define __MU_QUERY_HH__ #define __MU_QUERY_HH__
#include <memory> #include <memory>
#include <optional>
#include <glib.h> #include <glib.h>
#include <mu-store.hh> #include <mu-store.hh>
#include <mu-query-results.hh> #include <mu-query-results.hh>
#include <utils/mu-utils.hh> #include <utils/mu-utils.hh>
#include <utils/mu-option.hh>
#include <message/mu-message.hh> #include <message/mu-message.hh>
namespace Mu { namespace Mu {
@ -44,10 +44,10 @@ public:
* @return the query-results, or Nothing in case of error. * @return the query-results, or Nothing in case of error.
*/ */
Option<QueryResults> run(const std::string& expr = "", Option<QueryResults> run(const std::string& expr = "",
std::optional<Field::Id> sortfield_id = {}, Option<Field::Id> sortfield_id = {},
QueryFlags flags = QueryFlags::None, QueryFlags flags = QueryFlags::None,
size_t maxnum = 0) const; size_t maxnum = 0) const;
/** /**
* run a Xapian query to count the number of matches; for the syntax, please * run a Xapian query to count the number of matches; for the syntax, please

View File

@ -44,6 +44,7 @@
#include "utils/mu-str.h" #include "utils/mu-str.h"
#include "utils/mu-utils.hh" #include "utils/mu-utils.hh"
#include "utils/mu-option.hh"
#include "utils/mu-command-parser.hh" #include "utils/mu-command-parser.hh"
#include "utils/mu-readline.hh" #include "utils/mu-readline.hh"
@ -119,7 +120,7 @@ private:
const Option<QueryMatch&> qm, const Option<QueryMatch&> qm,
MuMsgOptions opts) const; MuMsgOptions opts) const;
Sexp::List move_docid(Store::Id docid, std::optional<std::string> flagstr, Sexp::List move_docid(Store::Id docid, Option<std::string> flagstr,
bool new_name, bool no_view); bool new_name, bool no_view);
Sexp::List perform_move(Store::Id docid, Sexp::List perform_move(Store::Id docid,
@ -814,7 +815,7 @@ Sexp::List
Server::Private::perform_move(Store::Id docid, Server::Private::perform_move(Store::Id docid,
MuMsg* msg, MuMsg* msg,
const std::string& maildirarg, const std::string& maildirarg,
Flags flags, Flags flags,
bool new_name, bool new_name,
bool no_view) bool no_view)
{ {
@ -852,9 +853,9 @@ Server::Private::perform_move(Store::Id docid,
static Flags static Flags
calculate_message_flags(MuMsg* msg, std::optional<std::string> flagopt) calculate_message_flags(MuMsg* msg, Option<std::string> flagopt)
{ {
const auto flags = std::invoke([&]()->std::optional<Flags>{ const auto flags = std::invoke([&]()->Option<Flags>{
auto msgflags{mu_msg_get_flags(msg)}; auto msgflags{mu_msg_get_flags(msg)};
if (!flagopt) if (!flagopt)
return mu_msg_get_flags(msg); return mu_msg_get_flags(msg);
@ -870,10 +871,10 @@ calculate_message_flags(MuMsg* msg, std::optional<std::string> flagopt)
} }
Sexp::List Sexp::List
Server::Private::move_docid(Store::Id docid, Server::Private::move_docid(Store::Id docid,
std::optional<std::string> flagopt, Option<std::string> flagopt,
bool new_name, bool new_name,
bool no_view) bool no_view)
{ {
if (docid == Store::InvalidId) if (docid == Store::InvalidId)
throw Error{Error::Code::InvalidArgument, "invalid docid"}; throw Error{Error::Code::InvalidArgument, "invalid docid"};

View File

@ -631,7 +631,7 @@ Store::lock() const
Option<QueryResults> Option<QueryResults>
Store::run_query(const std::string& expr, Store::run_query(const std::string& expr,
std::optional<Field::Id> sortfield_id, Option<Field::Id> sortfield_id,
QueryFlags flags, size_t maxnum) const QueryFlags flags, size_t maxnum) const
{ {
return xapian_try([&] { return xapian_try([&] {

View File

@ -34,6 +34,8 @@
#include <index/mu-indexer.hh> #include <index/mu-indexer.hh>
#include <mu-query-results.hh> #include <mu-query-results.hh>
#include <utils/mu-utils.hh> #include <utils/mu-utils.hh>
#include <utils/mu-option.hh>
#include <message/mu-message.hh> #include <message/mu-message.hh>
namespace Mu { namespace Mu {
@ -155,10 +157,10 @@ public:
* @return the query-results, or Nothing in case of error. * @return the query-results, or Nothing in case of error.
*/ */
std::mutex& lock() const; std::mutex& lock() const;
Option<QueryResults> run_query(const std::string& expr = "", Option<QueryResults> run_query(const std::string& expr = "",
std::optional<Field::Id> sortfield_id = {}, Option<Field::Id> sortfield_id = {},
QueryFlags flags = QueryFlags::None, QueryFlags flags = QueryFlags::None,
size_t maxnum = 0) const; size_t maxnum = 0) const;
/** /**
* run a Xapian query merely to count the number of matches; for the * run a Xapian query merely to count the number of matches; for the

View File

@ -32,16 +32,16 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
{ {
if (!call.is_call()) { if (!call.is_call()) {
throw Mu::Error{Error::Code::Command, throw Mu::Error{Error::Code::Command,
"expected call-sexpr but got %s", "expected call-sexpr but got %s",
call.to_sexp_string().c_str()}; call.to_sexp_string().c_str()};
} }
const auto& params{call.list()}; const auto& params{call.list()};
const auto cmd_it = cmap.find(params.at(0).value()); const auto cmd_it = cmap.find(params.at(0).value());
if (cmd_it == cmap.end()) if (cmd_it == cmap.end())
throw Mu::Error{Error::Code::Command, throw Mu::Error{Error::Code::Command,
"unknown command in call %s", "unknown command in call %s",
call.to_sexp_string().c_str()}; call.to_sexp_string().c_str()};
const auto& cinfo{cmd_it->second}; const auto& cinfo{cmd_it->second};
@ -65,9 +65,9 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
if (param_it == params.end()) { if (param_it == params.end()) {
if (arginfo.required) if (arginfo.required)
throw Mu::Error{Error::Code::Command, throw Mu::Error{Error::Code::Command,
"missing required parameter %s in call %s", "missing required parameter %s in call %s",
argname.c_str(), argname.c_str(),
call.to_sexp_string().c_str()}; call.to_sexp_string().c_str()};
continue; // not required continue; // not required
} }
@ -75,11 +75,11 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
// "no value" // "no value"
if (param_it->type() != arginfo.type && !(param_it->is_nil())) if (param_it->type() != arginfo.type && !(param_it->is_nil()))
throw Mu::Error{Error::Code::Command, throw Mu::Error{Error::Code::Command,
"parameter %s expects type %s, but got %s in call %s", "parameter %s expects type %s, but got %s in call %s",
argname.c_str(), argname.c_str(),
to_string(arginfo.type).c_str(), to_string(arginfo.type).c_str(),
to_string(param_it->type()).c_str(), to_string(param_it->type()).c_str(),
call.to_sexp_string().c_str()}; call.to_sexp_string().c_str()};
} }
// all passed parameters must be known // all passed parameters must be known
@ -88,9 +88,9 @@ Command::invoke(const Command::CommandMap& cmap, const Sexp& call)
return params.at(i).value() == arg.first; return params.at(i).value() == arg.first;
})) }))
throw Mu::Error{Error::Code::Command, throw Mu::Error{Error::Code::Command,
"unknown parameter %s in call %s", "unknown parameter %s in call %s",
params.at(i).value().c_str(), params.at(i).value().c_str(),
call.to_sexp_string().c_str()}; call.to_sexp_string().c_str()};
} }
if (cinfo.handler) if (cinfo.handler)
@ -105,8 +105,8 @@ find_param_node(const Parameters& params, const std::string& argname)
if (argname.empty() || argname.at(0) != ':') if (argname.empty() || argname.at(0) != ':')
throw Error(Error::Code::InvalidArgument, throw Error(Error::Code::InvalidArgument,
"property key must start with ':' but got '%s')", "property key must start with ':' but got '%s')",
argname.c_str()); argname.c_str());
for (size_t i = 1; i < params.size(); i += 2) { for (size_t i = 1; i < params.size(); i += 2) {
if (i + 1 != params.size() && params.at(i).is_symbol() && if (i + 1 != params.size() && params.at(i).is_symbol() &&
@ -121,63 +121,63 @@ static Error
wrong_type(Sexp::Type expected, Sexp::Type got) wrong_type(Sexp::Type expected, Sexp::Type got)
{ {
return Error(Error::Code::InvalidArgument, return Error(Error::Code::InvalidArgument,
"expected <%s> but got <%s>", "expected <%s> but got <%s>",
to_string(expected).c_str(), to_string(expected).c_str(),
to_string(got).c_str()); to_string(got).c_str());
} }
std::optional<std::string> Option<std::string>
Command::get_string(const Parameters& params, const std::string& argname) Command::get_string(const Parameters& params, const std::string& argname)
{ {
const auto it = find_param_node(params, argname); const auto it = find_param_node(params, argname);
if (it == params.end() || it->is_nil()) if (it == params.end() || it->is_nil())
return std::nullopt; return Nothing;
else if (!it->is_string()) else if (!it->is_string())
throw wrong_type(Sexp::Type::String, it->type()); throw wrong_type(Sexp::Type::String, it->type());
else else
return it->value(); return it->value();
} }
std::optional<std::string> Option<std::string>
Command::get_symbol(const Parameters& params, const std::string& argname) Command::get_symbol(const Parameters& params, const std::string& argname)
{ {
const auto it = find_param_node(params, argname); const auto it = find_param_node(params, argname);
if (it == params.end() || it->is_nil()) if (it == params.end() || it->is_nil())
return std::nullopt; return Nothing;
else if (!it->is_symbol()) else if (!it->is_symbol())
throw wrong_type(Sexp::Type::Symbol, it->type()); throw wrong_type(Sexp::Type::Symbol, it->type());
else else
return it->value(); return it->value();
} }
std::optional<int> Option<int>
Command::get_int(const Parameters& params, const std::string& argname) Command::get_int(const Parameters& params, const std::string& argname)
{ {
const auto it = find_param_node(params, argname); const auto it = find_param_node(params, argname);
if (it == params.end() || it->is_nil()) if (it == params.end() || it->is_nil())
return std::nullopt; return Nothing;
else if (!it->is_number()) else if (!it->is_number())
throw wrong_type(Sexp::Type::Number, it->type()); throw wrong_type(Sexp::Type::Number, it->type());
else else
return ::atoi(it->value().c_str()); return ::atoi(it->value().c_str());
} }
std::optional<unsigned> Option<unsigned>
Command::get_unsigned(const Parameters& params, const std::string& argname) Command::get_unsigned(const Parameters& params, const std::string& argname)
{ {
if (auto val = get_int(params, argname); val && *val >= 0) if (auto val = get_int(params, argname); val && *val >= 0)
return val; return val;
else else
return std::nullopt; return Nothing;
} }
std::optional<bool> Option<bool>
Command::get_bool(const Parameters& params, const std::string& argname) Command::get_bool(const Parameters& params, const std::string& argname)
{ {
const auto it = find_param_node(params, argname); const auto it = find_param_node(params, argname);
if (it == params.end()) if (it == params.end())
return std::nullopt; return Nothing;
else if (!it->is_symbol()) else if (!it->is_symbol())
throw wrong_type(Sexp::Type::Symbol, it->type()); throw wrong_type(Sexp::Type::Symbol, it->type());
else else

View File

@ -26,10 +26,10 @@
#include <unordered_map> #include <unordered_map>
#include <functional> #include <functional>
#include <algorithm> #include <algorithm>
#include <optional>
#include "utils/mu-error.hh" #include "utils/mu-error.hh"
#include "utils/mu-sexp.hh" #include "utils/mu-sexp.hh"
#include "utils/mu-option.hh"
namespace Mu { namespace Mu {
namespace Command { namespace Command {
@ -62,11 +62,11 @@ using ArgMap = std::unordered_map<std::string, ArgInfo>;
// The parameters to a Handler. // The parameters to a Handler.
using Parameters = Sexp::Seq; using Parameters = Sexp::Seq;
std::optional<int> get_int(const Parameters& parms, const std::string& argname); Option<int> get_int(const Parameters& parms, const std::string& argname);
std::optional<unsigned> get_unsigned(const Parameters& parms, const std::string& argname); Option<unsigned> get_unsigned(const Parameters& parms, const std::string& argname);
std::optional<bool> get_bool(const Parameters& parms, const std::string& argname); Option<bool> get_bool(const Parameters& parms, const std::string& argname);
std::optional<std::string> get_string(const Parameters& parms, const std::string& argname); Option<std::string> get_string(const Parameters& parms, const std::string& argname);
std::optional<std::string> get_symbol(const Parameters& parms, const std::string& argname); Option<std::string> get_symbol(const Parameters& parms, const std::string& argname);
std::vector<std::string> get_string_vec(const Parameters& params, const std::string& argname); std::vector<std::string> get_string_vec(const Parameters& params, const std::string& argname);
@ -86,7 +86,7 @@ static inline std::string
get_string_or(const Parameters& parms, const std::string& arg, const std::string& alt = ""){ get_string_or(const Parameters& parms, const std::string& arg, const std::string& alt = ""){
return get_string(parms, arg).value_or(alt); return get_string(parms, arg).value_or(alt);
} }
static inline std::string static inline std::string
get_symbol_or(const Parameters& parms, const std::string& arg, const std::string& alt = "nil") { get_symbol_or(const Parameters& parms, const std::string& arg, const std::string& alt = "nil") {
return get_symbol(parms, arg).value_or(alt); return get_symbol(parms, arg).value_or(alt);