commit 75dfabaefd80e4921a1260acaf137293b91a3563 Author: Himadri Bhattacharjee <107522312+lavafroth@users.noreply.github.com> Date: Sun Mar 22 13:46:03 2026 +0530 yas diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c60cf6a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "kwargs" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..06ed59c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "kwargs" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..e6c251c --- /dev/null +++ b/flake.lock @@ -0,0 +1,25 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1773840656, + "narHash": "sha256-9tpvMGFteZnd3gRQZFlRCohVpqooygFuy9yjuyRL2C0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9cf7092bdd603554bd8b63c216e8943cf9b12512", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7b8682a --- /dev/null +++ b/flake.nix @@ -0,0 +1,32 @@ +{ + description = "flake for github:lavafroth/shush"; + + outputs = + { + nixpkgs, + ... + }: + let + forAllSystems = + f: + nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed (system: f nixpkgs.legacyPackages.${system}); + in + { + + devShells = forAllSystems (pkgs: { + + default = pkgs.mkShell { + buildInputs = with pkgs; [ + stdenv.cc.cc.lib + ]; + LD_LIBRARY_PATH = with pkgs; lib.makeLibraryPath [ + wayland-protocols + wayland + libxkbcommon + libGL + ]; + }; + + }); + }; +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..3e5978b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,138 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + error::Error, +}; + +#[derive(Debug)] +pub struct Args { + datatypes: BTreeMap, + global: BTreeMap, + unseen: BTreeSet, +} + +#[derive(Debug)] +pub struct TemplateBlock { + datatype: AnyToken, + default: Option, +} + +impl Args { + fn new(template: &str) -> Result> { + let mut datatypes = BTreeMap::new(); + let mut unseen = BTreeSet::new(); + for argument in template.split_whitespace() { + let Some((argument, type_and_default)) = argument.split_once(":") else { + continue; + }; + let (datatype, default) = match type_and_default.split_once("=") { + Some((datatype, default)) => (datatype, Some(default)), + None => (type_and_default, None), + }; + let datatype = match datatype { + _ if datatype.starts_with("f64") => AnyToken::F64, + _ if datatype.starts_with("u64") => AnyToken::U64, + _ if datatype.starts_with("i64") => AnyToken::I64, + _ => AnyToken::String, + }; + + let default = match argument.split_once(".") { + Some((mutually_exclusive_section, _argument)) => { + unseen.insert(mutually_exclusive_section.to_string()); + None + } + None => { + unseen.insert(argument.to_string()); + if let Some(default) = default { + Some(datatype.parse(default)?) + } else { + None + } + } + }; + + datatypes.insert(argument.to_string(), TemplateBlock { datatype, default }); + } + Ok(Self { + unseen, + datatypes, + global: BTreeMap::default(), + }) + } +} + +#[derive(Debug, Clone)] +pub enum Any { + I64(i64), + U64(u64), + F64(f64), + String(String), +} + +#[derive(Debug)] +pub enum AnyToken { + I64, + U64, + F64, + String, +} + +impl AnyToken { + fn parse(&self, s: &str) -> Result> { + Ok(match self { + AnyToken::I64 => Any::I64(s.parse()?), + AnyToken::U64 => Any::U64(s.parse()?), + AnyToken::F64 => Any::F64(s.parse()?), + AnyToken::String => Any::String(s.parse()?), + }) + } +} + +fn main() { + let help_string = + "speed:f64\ntime:u64=30\nlight.wavelength:f64:nanometers\nlight.frequency:f64:petahertz"; + let mut args = Args::new(help_string).expect("bob"); + // println!("{:#?}", args); + + for arg in std::env::args().skip(1) { + let Some((key, value)) = arg.split_once("=") else { + println!("positional argument: {arg}"); + continue; + }; + + let Some(template) = args.datatypes.get(key) else { + continue; + }; + + let Ok(parsed_value) = template.datatype.parse(value) else { + eprintln!("{}", help_string); + return; + }; + + let section = match key.split_once(".") { + Some((mutually_exclusive, _key)) => mutually_exclusive, + None => key, + }; + + if !args.unseen.remove(section) { + eprintln!("a key under the `{}` section is already used", section); + eprintln!("{}", help_string); + return; + }; + args.global.insert(key.to_owned(), parsed_value); + } + // println!("{:#?}", args.unseen); + + for key in args.unseen.iter() { + let Some(TemplateBlock { + default: Some(v), .. + }) = args.datatypes.get(key) + else { + eprintln!("no values specified for `{}`", key); + eprintln!("{}", help_string); + return; + }; + args.global.insert(key.to_string(), v.clone()); + } + // println!("{}", help_string); + println!("{:#?}", args.global); +}