Move base BTreeMap API to alloc-only

This commit is contained in:
2025-11-05 07:32:32 +11:00
parent 0098df1252
commit dc833a24ed
5 changed files with 54 additions and 39 deletions

View File

@@ -9,4 +9,5 @@ authors.workspace = true
[features]
default = ["std"]
std = []
alloc = []
std = ["alloc"]

View File

@@ -3,7 +3,7 @@
* SPDX-License-Identifier: MIT
*/
use jaarg::{std::ParseMapResult, Opt, Opts};
use jaarg::{alloc::ParseMapResult, Opt, Opts};
use std::process::ExitCode;
fn main() -> ExitCode {
@@ -16,7 +16,8 @@ fn main() -> ExitCode {
let map = match OPTIONS.parse_map_easy() {
ParseMapResult::Map(map) => map,
ParseMapResult::Exit(code) => { return code; }
ParseMapResult::ExitSuccess => { return ExitCode::SUCCESS; }
ParseMapResult::ExitFailure => { return ExitCode::FAILURE; }
};
println!("{:?}", map);

40
jaarg/src/alloc.rs Normal file
View File

@@ -0,0 +1,40 @@
/* jaarg - Argument parser
* SPDX-FileCopyrightText: (C) 2025 Gay Pizza Specifications
* SPDX-License-Identifier: MIT
*/
extern crate alloc;
use alloc::collections::BTreeMap;
use alloc::string::String;
use crate::{Opts, ParseControl, ParseError, ParseResult};
impl Opts<&'static str> {
/// Parse an iterator of strings as arguments and return the results in a [`BTreeMap`].
///
/// Requires `features = ["alloc"]`.
pub fn parse_map<'a, S: AsRef<str> + 'a, I: Iterator<Item = S>>(&self, program_name: &str, args: I,
help: impl Fn(&str), error: impl FnOnce(&str, ParseError)
) -> ParseMapResult {
let mut out: BTreeMap<&'static str, String> = BTreeMap::new();
match self.parse(&program_name, args, |_program_name, id, opt, _name, arg| {
if opt.is_help() {
help(program_name);
Ok(ParseControl::Quit)
} else {
out.insert(id, arg.into());
Ok(ParseControl::Continue)
}
}, error) {
ParseResult::ContinueSuccess => ParseMapResult::Map(out),
ParseResult::ExitSuccess => ParseMapResult::ExitSuccess,
ParseResult::ExitError => ParseMapResult::ExitFailure,
}
}
}
/// The result of parsing commands with [Opts::parse_map].
pub enum ParseMapResult {
Map(BTreeMap<&'static str, String>),
ExitSuccess, ExitFailure
}

View File

@@ -13,5 +13,7 @@ include!("options.rs");
include!("argparse.rs");
include!("help.rs");
#[cfg(feature = "alloc")]
pub mod alloc;
#[cfg(feature = "std")]
pub mod std;

View File

@@ -5,18 +5,17 @@
extern crate std;
use crate::alloc::ParseMapResult;
use crate::{HandlerResult, HelpWriter, HelpWriterContext, Opt, Opts, ParseControl, ParseError, ParseResult, StandardFullHelpWriter, StandardShortUsageWriter};
use std::collections::BTreeMap;
use std::path::Path;
use std::rc::Rc;
use std::string::String;
use std::{env, eprintln, println};
impl<ID: 'static> Opts<ID> {
/// Wrapper around [Opts::parse] that gathers arguments from the command line and prints errors to stderr.
/// The errors are formatted in a standard user-friendly format.
///
/// Requires `features = [std]`.
/// Requires `features = ["std"]`.
pub fn parse_easy<'a>(&self, handler: impl FnMut(&str, &ID, &Opt<ID>, &str, &str) -> HandlerResult<'a, ParseControl>
) -> ParseResult {
let (program_name, argv) = Self::easy_args();
@@ -25,14 +24,14 @@ impl<ID: 'static> Opts<ID> {
/// Prints full help text for the options using the standard full.
///
/// Requires `features = [std]`.
/// Requires `features = ["std"]`.
pub fn print_full_help(&self, program_name: &str) {
self.print_help::<StandardFullHelpWriter<'_, ID>>(program_name);
}
/// Print help text to stdout using the provided help writer.
///
/// Requires `features = [std]`.
/// Requires `features = ["std"]`.
pub fn print_help<'a, W: HelpWriter<'a, ID>>(&'a self, program_name: &'a str) {
let ctx = HelpWriterContext { options: self, program_name };
println!("{}", W::new(ctx));
@@ -40,7 +39,7 @@ impl<ID: 'static> Opts<ID> {
/// Print help text to stderr using the provided help writer.
///
/// Requires `features = [std]`.
/// Requires `features = ["std"]`.
pub fn eprint_help<'a, W: HelpWriter<'a, ID>>(&'a self, program_name: &'a str) {
let ctx = HelpWriterContext { options: self, program_name };
eprintln!("{}", W::new(ctx));
@@ -63,39 +62,11 @@ impl<ID: 'static> Opts<ID> {
}
}
/// The result of parsing commands with [Opts::parse_map].
pub enum ParseMapResult {
Map(BTreeMap<&'static str, String>),
Exit(std::process::ExitCode),
}
impl Opts<&'static str> {
/// Parse an iterator of strings as arguments and return the results in a [BTreeMap].
///
/// Requires `features = [std]`.
pub fn parse_map<'a, S: AsRef<str> + 'a, I: Iterator<Item = S>>(&self, program_name: &str, args: I,
help: impl Fn(&str), error: impl FnOnce(&str, ParseError)
) -> ParseMapResult {
let mut out: BTreeMap<&'static str, String> = BTreeMap::new();
match self.parse(&program_name, args, |_program_name, id, opt, _name, arg| {
if opt.is_help() {
help(program_name);
Ok(ParseControl::Quit)
} else {
out.insert(id, arg.into());
Ok(ParseControl::Continue)
}
}, error) {
ParseResult::ContinueSuccess => ParseMapResult::Map(out),
ParseResult::ExitSuccess => ParseMapResult::Exit(std::process::ExitCode::SUCCESS),
ParseResult::ExitError => ParseMapResult::Exit(std::process::ExitCode::FAILURE),
}
}
/// Parse arguments from the command line and return the results in a [BTreeMap].
/// Parse arguments from the command line and return the results in a [`alloc::collections::BTreeMap`].
/// Help and errors are formatted in a standard user-friendly format.
///
/// Requires `features = [std]`.
/// Requires `features = ["std"]`.
pub fn parse_map_easy(&self) -> ParseMapResult {
let (program_name, argv) = Self::easy_args();
self.parse_map(&program_name, argv,