pub(crate) mod checker;
pub(crate) mod commit;
pub(crate) mod failure;
pub(crate) mod optset;
pub(crate) mod policy_delay;
pub(crate) mod policy_fwd;
pub(crate) mod policy_seq;
pub(crate) mod returnval;
pub(crate) mod storage;
pub(crate) mod style;
pub use self::checker::DefaultSetChecker;
pub use self::commit::ParserCommit;
pub use self::commit::ParserCommitWithValue;
pub use self::failure::FailManager;
pub use self::optset::HCOptSet;
pub use self::policy_delay::DelayPolicy;
pub use self::policy_fwd::FwdPolicy;
pub use self::policy_seq::SeqPolicy;
pub use self::returnval::Return;
pub use self::storage::AppServices;
pub use self::storage::AppStorage;
pub use self::storage::UsrValService;
pub use self::style::OptStyleManager;
pub use self::style::UserStyle;
pub use crate::acore::parser::Action;
use std::fmt::Debug;
use std::ops::Deref;
use std::ops::DerefMut;
use crate::args::Args;
use crate::ctx::InnerCtx;
use crate::ctx::Invoker;
use crate::set::OptValidator;
use crate::set::PrefixedValidator;
use crate::set::Set;
use crate::Error;
use crate::Uid;
#[derive(Debug, Clone)]
pub struct CtxSaver<'a> {
pub uid: Uid,
pub idx: usize,
pub ctx: InnerCtx<'a>,
}
pub trait Policy {
type Ret;
type Set;
type Inv<'a>;
type Error: Into<Error>;
fn parse(
&mut self,
set: &mut Self::Set,
inv: &mut Self::Inv<'_>,
args: Args,
) -> Result<Self::Ret, Self::Error>;
}
pub trait PolicySettings {
fn style_manager(&self) -> &OptStyleManager;
fn style_manager_mut(&mut self) -> &mut OptStyleManager;
fn strict(&self) -> bool;
fn styles(&self) -> &[UserStyle];
fn no_delay(&self) -> Option<&[String]>;
fn overload(&self) -> bool;
fn prepolicy(&self) -> bool;
fn set_strict(&mut self, strict: bool) -> &mut Self;
fn set_styles(&mut self, styles: Vec<UserStyle>) -> &mut Self;
fn set_no_delay(&mut self, name: impl Into<String>) -> &mut Self;
fn set_overload(&mut self, overload: bool) -> &mut Self;
fn set_prepolicy(&mut self, prepolicy: bool) -> &mut Self;
}
pub trait PolicyParser<P>
where
P: Policy,
{
type Error: Into<Error>;
fn parse_env(&mut self) -> Result<P::Ret, Self::Error>
where
P: Default,
{
self.parse(Args::from_env())
}
fn parse(&mut self, args: Args) -> Result<P::Ret, Self::Error>
where
P: Default,
{
let mut policy = P::default();
self.parse_policy(args, &mut policy)
}
fn parse_env_policy(&mut self, policy: &mut P) -> Result<P::Ret, Self::Error> {
let args = Args::from_env();
self.parse_policy(args, policy)
}
fn parse_policy(&mut self, args: Args, policy: &mut P) -> Result<P::Ret, Self::Error>;
}
#[derive(Debug, Default)]
pub struct Parser<S, P: Policy<Set = S>> {
pub policy: P,
pub optset: S,
}
impl<S, P: Policy<Set = S>> Deref for Parser<S, P> {
type Target = S;
fn deref(&self) -> &Self::Target {
&self.optset
}
}
impl<S, P: Policy<Set = S>> DerefMut for Parser<S, P> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.optset
}
}
impl<S, P: Policy<Set = S>> Parser<S, P> {
pub fn new(policy: P, optset: S) -> Self {
Self { optset, policy }
}
pub fn policy(&self) -> &P {
&self.policy
}
pub fn policy_mut(&mut self) -> &mut P {
&mut self.policy
}
pub fn set_policy(&mut self, policy: P) -> &mut Self {
self.policy = policy;
self
}
pub fn optset(&self) -> &S {
&self.optset
}
pub fn optset_mut(&mut self) -> &mut S {
&mut self.optset
}
pub fn set_optset(&mut self, optset: S) -> &mut Self {
self.optset = optset;
self
}
}
impl<'a, S, P> Parser<HCOptSet<'a, S>, P>
where
S: Default,
P: Policy<Set = HCOptSet<'a, S>, Inv<'a> = Invoker<'a, HCOptSet<'a, S>>>,
{
pub fn new_policy(policy: P) -> Self {
Self::new_with(policy, S::default(), Invoker::default())
}
pub fn new_with(policy: P, optset: S, invoker: Invoker<'a, HCOptSet<'a, S>>) -> Self {
Self {
policy,
optset: HCOptSet::new(optset, invoker),
}
}
}
impl<'a, S, P> Parser<HCOptSet<'a, S>, P>
where
S: Set,
P: Policy<Set = HCOptSet<'a, S>, Inv<'a> = Invoker<'a, HCOptSet<'a, S>>>,
{
pub fn reset(&mut self) -> Result<&mut Self, Error> {
self.optset.reset()?;
Ok(self)
}
pub fn init(&mut self) -> Result<(), Error> {
self.optset.init()
}
pub fn parse(&mut self, args: Args) -> Result<<P as Policy>::Ret, Error> {
PolicyParser::<P>::parse_policy(&mut self.optset, args, &mut self.policy)
}
}
impl<S, P> PolicySettings for Parser<S, P>
where
P: Policy<Set = S> + PolicySettings,
{
fn style_manager(&self) -> &OptStyleManager {
self.policy().style_manager()
}
fn style_manager_mut(&mut self) -> &mut OptStyleManager {
self.policy_mut().style_manager_mut()
}
fn strict(&self) -> bool {
self.policy().strict()
}
fn styles(&self) -> &[UserStyle] {
self.policy().styles()
}
fn no_delay(&self) -> Option<&[String]> {
self.policy().no_delay()
}
fn overload(&self) -> bool {
self.policy().overload()
}
fn prepolicy(&self) -> bool {
self.policy().prepolicy()
}
fn set_strict(&mut self, strict: bool) -> &mut Self {
self.policy_mut().set_strict(strict);
self
}
fn set_styles(&mut self, styles: Vec<UserStyle>) -> &mut Self {
self.policy_mut().set_styles(styles);
self
}
fn set_no_delay(&mut self, name: impl Into<String>) -> &mut Self {
self.policy_mut().set_no_delay(name);
self
}
fn set_overload(&mut self, overload: bool) -> &mut Self {
self.policy_mut().set_overload(overload);
self
}
fn set_prepolicy(&mut self, ignore_failure: bool) -> &mut Self {
self.policy_mut().set_prepolicy(ignore_failure);
self
}
}
impl<S, P> OptValidator for Parser<S, P>
where
S: OptValidator,
P: Policy<Set = S>,
{
type Error = Error;
fn check(&mut self, name: &str) -> Result<bool, Self::Error> {
OptValidator::check(&mut self.optset, name).map_err(Into::into)
}
fn split<'b>(
&self,
name: &std::borrow::Cow<'b, str>,
) -> Result<(std::borrow::Cow<'b, str>, std::borrow::Cow<'b, str>), Self::Error> {
OptValidator::split(&self.optset, name).map_err(Into::into)
}
}
impl<S, P: Policy<Set = S>> PrefixedValidator for Parser<S, P>
where
S: PrefixedValidator,
P: Policy<Set = S>,
{
type Error = Error;
fn reg_prefix(&mut self, val: &str) -> Result<(), Self::Error> {
PrefixedValidator::reg_prefix(&mut self.optset, val).map_err(Into::into)
}
fn unreg_prefix(&mut self, val: &str) -> Result<(), Self::Error> {
PrefixedValidator::unreg_prefix(&mut self.optset, val).map_err(Into::into)
}
}
impl<S, P> Parser<S, P>
where
P: Policy<Set = S> + PolicySettings,
{
pub fn enable_combined(&mut self) -> &mut Self {
self.style_manager_mut().push(UserStyle::CombinedOption);
self
}
pub fn enable_embedded_plus(&mut self) -> &mut Self {
self.style_manager_mut().push(UserStyle::EmbeddedValuePlus);
self
}
pub fn enable_flag(&mut self) -> &mut Self {
self.style_manager_mut().push(UserStyle::Flag);
self
}
}
impl<S, P: Policy<Set = S>> PolicyParser<P> for Parser<S, P>
where
S: Set + PolicyParser<P, Error = Error>,
{
type Error = Error;
fn parse(&mut self, args: Args) -> Result<<P as Policy>::Ret, Self::Error>
where
P: Default,
{
PolicyParser::<P>::parse_policy(&mut self.optset, args, &mut self.policy)
}
fn parse_policy(
&mut self,
args: Args,
policy: &mut P,
) -> Result<<P as Policy>::Ret, Self::Error> {
PolicyParser::<P>::parse_policy(&mut self.optset, args, policy)
}
}