Documentation
/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--

Dia-Args

Copyright (C) 2018-2019, 2021-2025  Anonymous

There are several releases over multiple years,
they are listed as ranges, such as: "2018-2019".

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/

use {
    alloc::collections::BTreeSet,
    crate::{MergeOption, Result},
};

const OPTION_TEST: &[&str] = &["-t", "--test"];
const OPTION_DEBUG: &[&str] = &["--debug"];
const OPTION_FLAG: &[&str] = &["-f", "--flag"];
const OPTION_SOME: &[&str] = &["--some"];

#[test]
fn args() -> Result<()> {
    let mut args = crate::parse_strings([
        "cmd", "-b", "--src=123", "/path/to/some/file", "--some", "none", "--type", "ogg", "--type", "m4v", "--type", "M4V",
        "--ids", "9", "--ids", "1", "--ids", "99", "--ids", "22", "--ids", "333",
        "--", "sub", "args", "--can", "--be", "--malformed:~!@#$%^&*()_+", "-", "--", "-", "--",
    ])?;
    assert!(args.take_args().is_err());
    assert_eq!(args.take_sub_args(), &["sub", "args", "--can", "--be", "--malformed:~!@#$%^&*()_+", "-", "--", "-", "--"]);

    assert_eq!(true, args.take(&["-b"])?.unwrap());
    assert_eq!(123_u8, args.take(&["--src"])?.unwrap());
    assert!(args.take::<u8>(&["--SRC"])?.is_none());
    assert_eq!("none", args.take::<String>(OPTION_SOME)?.unwrap());

    assert_eq!(&["ogg", "m4v", "M4V"], args.take_vec::<String>(&["--type"])?.unwrap().as_slice());
    assert_eq!(&[9, 1, 99, 22, 333], args.take_vec(&["--ids"])?.unwrap().as_slice());

    Ok(())
}

#[test]
fn merges() -> Result<()> {
    let mut final_args = crate::parse_strings(["--test=true", "-f=0", "--flag=1", "--debug=true"])?;

    let mut args = crate::parse_strings(["-t=false", "--flag=9", "--ignored=true"])?;
    assert!(final_args.merge_options(&mut args, &[], MergeOption::IgnoreExisting).is_err());
    assert!(final_args.merge_options(&mut args, &[OPTION_DEBUG, OPTION_TEST, OPTION_FLAG, &[]], MergeOption::IgnoreExisting).is_err());
    assert_eq!(final_args.merge_options(&mut args, &[OPTION_TEST, OPTION_FLAG], MergeOption::IgnoreExisting)?, 0);
    assert_eq!(args.take(OPTION_TEST)?, Some(false));
    assert_eq!(args.take(&["--ignored"])?, Some(true));
    assert_eq!(final_args.take(OPTION_TEST)?, Some(true));
    assert_eq!(final_args.take(OPTION_DEBUG)?, Some(true));
    assert_eq!(final_args.take_vec::<u8>(OPTION_FLAG)?.unwrap().into_iter().collect::<BTreeSet<_>>(), vec![0, 1].into_iter().collect());

    let mut args = crate::parse_strings(["--test=false", "--some=none", "-d=false", "-f=3"])?;
    assert_eq!(
        final_args.merge_options(&mut args, &[OPTION_TEST, OPTION_FLAG, OPTION_SOME, &["-d"]], MergeOption::TakeAll)?,
        4,
    );
    assert!(args.options.is_empty());
    assert_eq!(final_args.take(OPTION_TEST)?, Some(false));
    assert_eq!(final_args.take(&["-d"])?, Some(false));
    assert_eq!(final_args.take_vec::<u8>(OPTION_FLAG)?.unwrap(), &[3]);
    assert_eq!(final_args.take::<String>(OPTION_SOME)?.unwrap(), "none");

    Ok(())
}