From b6eec3784dfe43c2cddef0c2dcff72c0b39e6d90 Mon Sep 17 00:00:00 2001 From: libglfw Date: Sat, 2 Nov 2024 14:55:06 -0700 Subject: [PATCH] remove command_system_macros --- lib/command_system_macros/Cargo.toml | 12 --- lib/command_system_macros/src/lib.rs | 151 --------------------------- lib/commands/Cargo.toml | 1 - lib/commands/src/lib.rs | 104 +++++++++++++++--- lib/commands/src/string.rs | 1 + 5 files changed, 93 insertions(+), 176 deletions(-) delete mode 100644 lib/command_system_macros/Cargo.toml delete mode 100644 lib/command_system_macros/src/lib.rs diff --git a/lib/command_system_macros/Cargo.toml b/lib/command_system_macros/Cargo.toml deleted file mode 100644 index 7d2aa1b0..00000000 --- a/lib/command_system_macros/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "command_system_macros" -version = "0.1.0" -edition = "2021" - -[lib] -proc-macro = true - -[dependencies] -quote = "1.0" -proc-macro2 = "1.0" -syn = "2.0" diff --git a/lib/command_system_macros/src/lib.rs b/lib/command_system_macros/src/lib.rs deleted file mode 100644 index 1f863ec3..00000000 --- a/lib/command_system_macros/src/lib.rs +++ /dev/null @@ -1,151 +0,0 @@ -use proc_macro2::{Delimiter, TokenStream, TokenTree, Literal, Span}; -use syn::parse::{Parse, ParseStream, Result as ParseResult}; -use syn::{parse_macro_input, Token, Ident}; -use quote::{quote, quote_spanned}; - -enum CommandToken { - /// "typed argument" being a member of the `Token` enum in the - /// command parser crate. - /// - /// prefixed with `@` in the command macro. - TypedArgument(Ident, Span), - - /// interpreted as a literal string in the command input. - /// - /// no prefix in the command macro. - Literal(Literal, Span), -} - -impl Parse for CommandToken { - fn parse(input: ParseStream) -> ParseResult { - let lookahead = input.lookahead1(); - if lookahead.peek(Token![@]) { - // typed argument - input.parse::()?; - let ident = input.parse::()?; - Ok(Self::TypedArgument(ident.clone(), ident.span())) - } else if lookahead.peek(Ident) { - // literal string - let ident = input.parse::()?; - let lit = Literal::string(&format!("{ident}")); - Ok(Self::Literal(lit, ident.span())) - } else { - Err(input.error("expected a command token")) - } - } -} - -impl Into for CommandToken { - fn into(self) -> TokenStream { - match self { - Self::TypedArgument(ident, span) => quote_spanned! {span=> - Token::#ident - }, - - Self::Literal(lit, span) => quote_spanned! {span=> - Token::Value(vec![ #lit.to_string(), ]) - }, - }.into() - } -} - -struct Command { - tokens: Vec, - help: Literal, - cb: Literal, -} - -impl Parse for Command { - fn parse(input: ParseStream) -> ParseResult { - let mut tokens = Vec::::new(); - loop { - if input.peek(Token![,]) { - break; - } - - tokens.push(input.parse::()?); - } - input.parse::()?; - - let cb_ident = input.parse::()?; - let cb = Literal::string(&format!("{cb_ident}")); - input.parse::()?; - - let help = input.parse::()?; - - Ok(Self { - tokens, - cb, - help, - }) - } -} - -impl Into for Command { - fn into(self) -> TokenStream { - let Self { tokens, help, cb } = self; - let tokens = tokens.into_iter().map(Into::into).collect::>(); - - quote! { - Command { tokens: vec![#(#tokens),*], help: #help.to_string(), cb: #cb.to_string() } - } - } -} - -#[proc_macro] -pub fn commands(stream: proc_macro::TokenStream) -> proc_macro::TokenStream { - let stream: TokenStream = stream.into(); - let mut commands: Vec = Vec::new(); - - let mut top_level_tokens = stream.into_iter(); - 'a: loop { - // "command" - match top_level_tokens.next() { - Some(TokenTree::Ident(ident)) if format!("{ident}") == "command" => {} - None => break 'a, - _ => panic!("contents of commands! macro is invalid"), - } - // - match top_level_tokens.next() { - Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Parenthesis => { - let group_stream: proc_macro::TokenStream = group.stream().into(); - commands.push(parse_macro_input!(group_stream as Command).into()); - } - _ => panic!("contents of commands! macro is invalid"), - } - // ; - match top_level_tokens.next() { - Some(TokenTree::Punct(punct)) if format!("{punct}") == ";" => {} - _ => panic!("contents of commands! macro is invalid"), - } - } - - let command_registrations = commands - .iter() - .map(|v| -> TokenStream { quote! { tree.register_command(#v); }.into() }) - .collect::(); - - let res = quote! { - lazy_static::lazy_static! { - static ref COMMAND_TREE: TreeBranch = { - let mut tree = TreeBranch { - current_command_key: None, - possible_tokens: vec![], - branches: HashMap::new(), - }; - - #command_registrations - - tree.sort_tokens(); - - // println!("{{tree:#?}}"); - - tree - }; - } - }; - - // panic!("{res}"); - - res.into() -} diff --git a/lib/commands/Cargo.toml b/lib/commands/Cargo.toml index 1d1ac480..efff1dea 100644 --- a/lib/commands/Cargo.toml +++ b/lib/commands/Cargo.toml @@ -8,7 +8,6 @@ crate-type = ["cdylib"] [dependencies] lazy_static = { workspace = true } -command_system_macros = { path = "../command_system_macros" } uniffi = { version = "0.25" } diff --git a/lib/commands/src/lib.rs b/lib/commands/src/lib.rs index 0217dec7..6b787403 100644 --- a/lib/commands/src/lib.rs +++ b/lib/commands/src/lib.rs @@ -9,8 +9,6 @@ mod string; mod token; use token::*; -use command_system_macros::commands; - // todo!: move all this stuff into a different file // lib.rs should just have exported symbols and command definitions @@ -69,23 +67,105 @@ impl TreeBranch { } } +#[derive(Clone)] struct Command { tokens: Vec, help: String, cb: String, } -// todo: aliases -// todo: categories -commands! { - command(help, help, "Shows the help command"); +fn command(tokens: &[&Token], help: &str, cb: &str) -> Command { + Command { + tokens: tokens.iter().map(|&x| x.clone()).collect(), + help: help.to_string(), + cb: cb.to_string(), + } +} - command(member new, member_new, "Creates a new system member"); - command(member @MemberRef, member_show, "Shows information about a member"); - command(member @MemberRef description, member_desc_show, "Shows a member's description"); - command(member @MemberRef description @FullString, member_desc_update, "Changes a member's description"); - command(member @MemberRef privacy, member_privacy_show, "Displays a member's current privacy settings"); - command(member @MemberRef privacy @MemberPrivacyTarget @PrivacyLevel, member_privacy_update, "Changes a member's privacy settings"); +mod commands { + use super::Token; + + use super::command; + use super::Token::*; + + fn cmd(value: &str) -> Token { + Token::Value(vec![value.to_string()]) + } + + pub fn cmd_with_alias(value: &[&str]) -> Token { + Token::Value(value.iter().map(|x| x.to_string()).collect()) + } + + // todo: this needs to have less ampersands -alyssa + pub fn happy() -> Vec { + let system = &cmd_with_alias(&["system", "s"]); + let member = &cmd_with_alias(&["member", "m"]); + let description = &cmd_with_alias(&["description", "desc"]); + let privacy = &cmd_with_alias(&["privacy", "priv"]); + vec![ + command(&[&cmd("help")], "help", "Shows the help command"), + command( + &[system], + "system_show", + "Shows information about your system", + ), + command(&[system, &cmd("new")], "system_new", "Creates a new system"), + command( + &[member, &cmd_with_alias(&["new", "n"])], + "member_new", + "Creates a new system member", + ), + command( + &[member, &MemberRef], + "member_show", + "Shows information about a member", + ), + command( + &[member, &MemberRef, description], + "member_desc_show", + "Shows a member's description", + ), + command( + &[member, &MemberRef, description, &FullString], + "member_desc_update", + "Changes a member's description", + ), + command( + &[member, &MemberRef, privacy], + "member_privacy_show", + "Displays a member's current privacy settings", + ), + command( + &[ + member, + &MemberRef, + privacy, + &MemberPrivacyTarget, + &PrivacyLevel, + ], + "member_privacy_update", + "Changes a member's privacy settings", + ), + ] + } +} + +lazy_static::lazy_static! { + static ref COMMAND_TREE: TreeBranch = { + let mut tree = TreeBranch { + current_command_key: None, + possible_tokens: vec![], + branches: HashMap::new(), + }; + + commands::happy().iter().for_each(|x| tree.register_command(x.clone())); + + tree.sort_tokens(); + + // println!("{{tree:#?}}"); + + tree + }; } pub enum CommandResult { diff --git a/lib/commands/src/string.rs b/lib/commands/src/string.rs index bc65c8a0..0ea7659a 100644 --- a/lib/commands/src/string.rs +++ b/lib/commands/src/string.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; lazy_static::lazy_static! { // Dictionary of (left, right) quote pairs // Each char in the string is an individual quote, multi-char strings imply "one of the following chars" + // Certain languages can have quote patterns that have a different character for open and close pub static ref QUOTE_PAIRS: HashMap = { let mut pairs = HashMap::new();