use crate::{
parser::{ErrorInfo, MiddleArg},
vector::flag::FlagSearch,
Command, Flag, FlagValue, Vector,
};
use std::collections::VecDeque;
#[derive(Debug, Clone)]
pub struct Context {
pub raw_args: Vec<String>,
pub args: VecDeque<String>,
pub common_flags: Vector<Vector<Flag>>,
pub routes: Vector<String>,
pub exe_path: String,
pub common_flags_values: Vector<(String, FlagValue)>,
pub local_flags_values: Vector<(String, FlagValue)>,
pub parsing_args: Option<VecDeque<MiddleArg>>,
pub error_info_list: Vector<ErrorInfo>,
}
impl Context {
pub fn new(
raw_args: Vec<String>,
args: VecDeque<String>,
common_flags: Vector<Flag>,
routes: Vector<String>,
exe_path: String,
) -> Context {
Context {
raw_args,
args,
common_flags: Vector(Some(vec![common_flags])),
routes: routes.into(),
exe_path,
common_flags_values: Vector::default(),
local_flags_values: Vector::default(),
parsing_args: None,
error_info_list: Vector::default(),
}
}
pub fn with_all_field(
raw_args: Vec<String>,
args: VecDeque<String>,
common_flags: Vector<Vector<Flag>>,
exe_path: String,
routes: Vector<String>,
common_flags_values: Vector<(String, FlagValue)>,
local_flags_values: Vector<(String, FlagValue)>,
parsing_args: Option<VecDeque<MiddleArg>>,
error_info_list: Vector<ErrorInfo>,
) -> Context {
Context {
raw_args,
args,
common_flags,
routes,
exe_path,
common_flags_values,
local_flags_values,
parsing_args,
error_info_list,
}
}
pub fn args(mut self, args: VecDeque<String>) -> Self {
self.args = args;
self
}
pub fn exe_path(&self) -> &str {
&self.exe_path
}
pub fn change_exe_path(mut self, path: String) {
self.exe_path = path;
}
pub fn push_back_to_parsing_args(&mut self, middle_arg: MiddleArg) {
match self.parsing_args {
None => {
self.parsing_args = Some({
let mut inner = VecDeque::new();
inner.push_back(middle_arg);
inner
})
}
Some(ref mut vd) => (*vd).push_back(middle_arg),
}
}
pub fn push_front_to_parsing_args(&mut self, middle_arg: MiddleArg) {
match self.parsing_args {
None => {
self.parsing_args = Some({
let mut inner = VecDeque::new();
inner.push_front(middle_arg);
inner
})
}
Some(ref mut vd) => (*vd).push_back(middle_arg),
}
}
pub fn take_flag_value_of(
&mut self,
flag_name: &str,
current_command: &Command,
) -> Option<FlagValue> {
match self.take_local_flag_value_of(flag_name, current_command) {
None => self.take_common_flag_value_of(flag_name, current_command),
val => val,
}
}
pub fn take_inputted_flag_value_of(&mut self, flag_name: &str) -> Option<FlagValue> {
match self.take_inputted_local_flag_value_of(flag_name) {
None => self.take_inputted_common_flag_value_of(flag_name),
val => val,
}
}
pub fn take_local_flag_value_of(
&mut self,
flag_name: &str,
current_command: &Command,
) -> Option<FlagValue> {
match self.take_inputted_common_flag_value_of(flag_name) {
None => match current_command.l_flags.find(flag_name) {
None => None,
Some(f) => Some(f.default_value.clone()),
},
val => val,
}
}
pub fn take_common_flag_value_of(
&mut self,
flag_name: &str,
current_command: &Command,
) -> Option<FlagValue> {
match self.take_inputted_common_flag_value_of(flag_name) {
None => match (¤t_command.c_flags, &self.common_flags).find(flag_name) {
None => None,
Some(f) => Some(f.default_value.clone()),
},
val => val,
}
}
pub fn take_inputted_local_flag_value_of(&mut self, flag_name: &str) -> Option<FlagValue> {
match self.local_flags_values {
Vector(None) => None,
Vector(Some(ref mut local)) => {
match local.iter().position(|(name, _)| name == flag_name) {
Some(index) => {
let (_, val) = local.remove(index);
Some(val)
}
None => None,
}
}
}
}
pub fn take_inputted_common_flag_value_of(&mut self, flag_name: &str) -> Option<FlagValue> {
match self.common_flags_values {
Vector(None) => None,
Vector(Some(ref mut common)) => {
match common.iter().position(|(name, _)| name == flag_name) {
Some(index) => {
let (_, val) = common.remove(index);
Some(val)
}
None => None,
}
}
}
}
pub fn get_flag_value_of(
&self,
flag_name: &str,
current_command: &Command,
) -> Option<FlagValue> {
match self.get_local_flag_value_of(flag_name, current_command) {
None => self.get_common_flag_value_of(flag_name, current_command),
flag_val => flag_val,
}
}
pub fn get_inputted_flag_value_of(&self, flag_name: &str) -> Option<FlagValue> {
match self.get_inputted_local_flag_value_of(flag_name) {
None => self.get_inputted_common_flag_value_of(flag_name),
flag_val => flag_val,
}
}
pub fn get_common_flag_value_of(
&self,
flag_name: &str,
current_command: &Command,
) -> Option<FlagValue> {
match self.get_inputted_common_flag_value_of(flag_name) {
None => match (¤t_command.c_flags, &self.common_flags).find(flag_name) {
Some(f) => Some(f.default_value.clone()),
None => None,
},
Some(FlagValue::None) => {
match (¤t_command.c_flags, &self.common_flags).find(flag_name) {
Some(f) => Some(f.derive_flag_value_if_no_value()),
None => None,
}
}
val => val,
}
}
pub fn get_local_flag_value_of(
&self,
flag_name: &str,
current_command: &Command,
) -> Option<FlagValue> {
match self.get_inputted_local_flag_value_of(flag_name) {
None => match current_command.l_flags.find(flag_name) {
Some(f) => Some(f.default_value.clone()),
None => None,
},
Some(FlagValue::None) => match current_command.l_flags.find(flag_name) {
Some(f) => Some(f.derive_flag_value_if_no_value()),
None => None,
},
val => val,
}
}
pub fn get_inputted_local_flag_value_of(&self, flag_name: &str) -> Option<FlagValue> {
match &self.local_flags_values {
Vector(None) => None,
Vector(Some(local)) => match local.iter().find(|(name, _)| name == flag_name) {
None => None,
Some((_, flag_val)) => Some(flag_val.to_owned()),
},
}
}
pub fn get_inputted_common_flag_value_of(&self, flag_name: &str) -> Option<FlagValue> {
match &self.common_flags_values {
Vector(None) => None,
Vector(Some(common)) => match common.iter().find(|(name, _)| name == flag_name) {
None => None,
Some((_, flag_val)) => Some(flag_val.to_owned()),
},
}
}
pub fn is_flag_true(&self, name: &str, current_command: &Command) -> bool {
Some(FlagValue::Bool(true)) == self.get_flag_value_of(name, current_command)
}
pub fn depth(&self) -> usize {
self.common_flags.len()
}
pub fn has_no_error(&self) -> bool {
self.error_info_list.is_empty()
}
pub fn num_of_error(&self) -> usize {
self.error_info_list.len()
}
pub fn has_error(&self) -> bool {
self.error_info_list.has_at_least_one()
}
pub fn first_error(&self) -> Option<&ErrorInfo> {
self.error_info_list.first()
}
}
impl<'a> From<Vec<String>> for Context {
fn from(raw_args: Vec<String>) -> Context {
let args = VecDeque::from(raw_args.clone());
let exe_path = match raw_args.get(0) {
Some(str) => String::from(str),
None => String::new(),
};
Context {
raw_args,
args,
common_flags: Vector::default(),
routes: Vector::default(),
exe_path,
common_flags_values: Vector::default(),
local_flags_values: Vector::default(),
parsing_args: None,
error_info_list: Vector::default(),
}
}
}