args_flags_1 0.2.0

A library for manipulating with flags
Documentation
//! # Flag Detection Crate
//! this crate detect flag in syntax
//! command -flag value_of_flag
//! ## Examples
//! ```
//! flagfinder -timeout 1000
//! ```
//! # Examples
//! ```
//! use std::env;
//!
//! let prefix: &str = "-";
//! let args: env::Args = env::args();
//! let detect: FlagDetect = FlagDetect::new(prefix).from_args(args);
//!
//! // gives back value of the flag
//! let s_flag: Option<String> = detect.find("-s");
//! match s_flag {
//!     Some(x) => {},
//!     None => {}
//! }
//!
//! ```


use std::env::Args;

// #[derive(New)]
/// Flag 
/// next value to flag is value for the flag
/// syntax of command used is <prefix><key> <value>
///
/// # Examples 
/// ```
/// let flag = Flag::new("s", "1000");
///
/// ```
#[derive(Debug)]
pub struct Flag {
    /// key or text of flag
    key: String,
    /// value of the flag
    val: String
}
impl Flag {
    pub fn new(key: &str, val: &str) -> Self {
        Self {key: key.to_string(), val: val.to_string()}
    }
    pub fn same(&self, input: &str) -> bool {
        self.key == input
    }
    pub fn get(&self) -> &str {
        &self.val
    }
}

/// This struct is Vec for our flags
/// implementation of using flags
///
/// show: -s mark
///
/// # Examples
/// ## get all obtained flags
/// ```
/// let flags: Vec<Flag> = FlagDetect::get("-", std::env::args())
/// ```
///
/// ## working with specific flag
/// ```
/// use std::env;
///
/// let prefix: &str = "-";
/// let args: env::Args = env::args();
/// let detect: FlagDetect = FlagDetect::new(prefix).from_args(args);
///
/// // gives back value of the flag
/// let s_flag: Option<String> = detect.find("-s");
/// match s_flag {
///     Some(x) => {},
///     None => {}
/// }
/// ```
pub struct FlagDetect {
    prefix: String,
    flags: Vec<Flag>
}

/// # Static Flag Only
/// basicly getting only flag not their specified values
/// ```
/// let prefix = "-";
/// // basic flag exporter 
/// StaicOnlyFlag::get(prefix, std::env::args());
///
/// // basic one letter exporter
/// StaicOnlyFlag::getn(prefix, std::env::args());
/// ```
pub struct StaticFlagOnly {}
impl StaticFlagOnly {
    /// get flags only (ignores everything else and not works with values of them)
    /// ```
    /// input: -a -b -c r -avc
    /// returns vec!['a', 'b', 'c', 'avc']
    /// ```
    pub fn get(prefix: &str, args: Args) -> Vec<String> {
        let size = args.len();
        args.rev().take(size-prefix.len())
            .map(|x| x.replace(prefix, ""))
            .filter(|x| x.contains(prefix))
            .rev().collect()
    }
    /// get all arguments with prefix and then split it by one
    /// ```
    /// input: -a -b -c r -kvd
    /// returns vec!['a', 'b', 'c', 'k', 'v', 'd']
    /// ```
    pub fn getn(prefix: &str, args: Args) -> Vec<String> {
        let x = self::StaticFlagOnly::get(prefix, args).join("");
        x.split("").map(|x| x.to_string()).collect()
    }
}

/// # Static Flag
/// Just get Arguments without doing anything else
/// Basicly getting flag (val: String, key: String)
///
/// ```
/// let prefix = "-";
///
/// // flag exporter
/// StaticFlag::get(prefix, std::env::args());
///
/// // flag exporter with more prefixes
/// StaticFlag::getn(vec![prefix], std::env::args());
/// ```
pub struct StaticFlag { }
impl StaticFlag {
    /// get all Flags from arguments pushed to your program
    /// Just get Arguments without doing anything else
    pub fn get(prefix: &str, args: Args) -> Vec<Flag> {
        let mut next = false;
        let mut flags = Vec::new();
        let mut last = "".to_string();
        for a1 in args {
            if a1.contains(prefix) {
                next = true;
                last = a1;
            } else if next {
                flags.push(Flag::new(&last, &a1));
            }
        }
        flags
    }
    pub fn getn(prefixn: Vec<&str>, args: Args) -> Vec<Flag> {
        let mut next = false;
        let mut flags = Vec::new();
        let mut last = "".to_string();
        for a in args {
            let prefixn = prefixn.clone();
            for prefix in prefixn {
                if a.contains(prefix) {
                    next = true;
                    last = a.clone();
                } else if next {
                    flags.push(Flag::new(&last, &a));
                }
            }
        }
        flags
    }
}

impl FlagDetect {
    /// # Eample 
    /// ```
    /// use args_flag_1::FlagDetect;
    /// use args_flag_1::Flag;
    ///
    /// fn main() {
    ///     let mut detector: FlagDetect = FlagDetect::new("-")
    ///     detector.from_args()
    /// }
    /// ```
    pub fn new(prefix: &str) -> Self {
        Self {prefix: prefix.to_string(), flags: Vec::new()}
    }
    pub fn new_args(prefix: &str, args: Args) -> Self {
        let mut sel = Self::new(prefix);
        sel.from_args(args);
        sel
    }

    /// generates flags from arguments (std::env::Args)
    pub fn from_args(&mut self, a: Args) {
        // a1 == String
        let mut next = false;
        let mut last = "".to_string();
        for a1 in a {
            if a1.contains(&self.prefix) {
                next = true;
                last = a1;
            } else if next {
                self.flags.push(Flag::new(&last, &a1));
            }
        }
    }

    /// tries to find flag using &str
    /// ```
    /// detect.find("-s") 
    /// ```
    pub fn find(&self, s: &str) -> Option<String> {
        for x in self.flags.iter() {
            if x.same(s) {
                return Some(x.get().to_string())
            }
        }
        None
    }
}