From 41eef3c4a5e838a354427c38d9f957a7b9042f0c Mon Sep 17 00:00:00 2001 From: George Lewis Date: Fri, 30 Apr 2021 21:11:37 -0400 Subject: [PATCH 01/10] done --- Cargo.lock | 44 +++++++++++++++++ Cargo.toml | 3 ++ macros/Cargo.toml | 14 ++++++ macros/src/lib.rs | 102 +++++++++++++++++++++++++++++++++++++++ src/lib/constants.rs | 14 +++--- src/lib/operators.rs | 24 ++++----- src/lib/representable.rs | 33 +++++++------ src/lib/variables.rs | 17 ++----- 8 files changed, 202 insertions(+), 49 deletions(-) create mode 100644 macros/Cargo.toml create mode 100644 macros/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 8dfaca8..94dc86a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,6 +153,14 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "macros" +version = "0.1.0" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "memchr" version = "2.3.4" @@ -186,6 +194,24 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "proc-macro2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + [[package]] name = "radix_trie" version = "0.2.1" @@ -263,6 +289,7 @@ dependencies = [ "dirs", "itertools", "lazy_static", + "macros", "rand", "rustyline", ] @@ -302,6 +329,17 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +[[package]] +name = "syn" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "unicode-segmentation" version = "1.7.1" @@ -314,6 +352,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + [[package]] name = "utf8parse" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index b7655e6..22065ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,9 @@ license = "MIT" [dependencies] +# Proc macros +macros = { path = "./macros" } + # For colored terminal output colored = "2" diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 index 0000000..95ce1aa --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "macros" +version = "0.1.0" +authors = ["George Lewis "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.9" +syn = "1.0.71" diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 0000000..4a09dfa --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,102 @@ +use proc_macro::TokenStream; +use syn::{Data, DeriveInput, Type, spanned::Spanned}; +use quote::{quote, quote_spanned, format_ident}; + +macro_rules! error { + ($span:expr, $msg:expr) => { + syn::Error::new($span, $msg).to_compile_error().into() + }; +} + +enum ImplType { + Iter, + Single +} + +// Returns impl type and the inner type +fn kind(ty: &Type) -> Result<(ImplType, &Type), TokenStream> { + Ok(match ty { + Type::Slice(ts) => { + (ImplType::Iter, ts.elem.as_ref()) + } + Type::Array(ta) => { + (ImplType::Iter, ta.elem.as_ref()) + } + Type::Reference(tr) => { + // Recurse! + kind(tr.elem.as_ref())? + } + Type::Path(_) => { + (ImplType::Single, ty) + } + _ => return Err(error!(ty.span(), "Representation type is not a regular type, array, nor slice")) + }) +} + +#[proc_macro_derive(Searchable, attributes(representation))] +pub fn searchable_derive(ts: TokenStream) -> TokenStream { + let ast = syn::parse(ts).unwrap(); + searchable_impl(&ast) +} + +fn searchable_impl(ast: &DeriveInput) -> TokenStream { + let name = &ast.ident; + + // Find tagged field + let field = match &ast.data { + Data::Struct(struc) => { + struc.fields.iter().find(|f| { + f.attrs.iter().any(|a| a.path.is_ident("representation")) + }) + }, + _ => return error!(ast.span(), "`Searchable` can only derive structs.") + }; + + let field = match field { + Some(f) => f, + None => return error!(ast.span(), "No `#[representable]` annotated member.") + }; + + let ty_span = field.ty.span(); + + // Determine impl type and get inner type of representation + let (kind, ty) = match kind(&field.ty) { + Ok(a) => a, + Err(ts) => return ts + }; + + // Enforce that the representation type has to be `AsRef` + let assert_ident = format_ident!("{}AssertAsRefStr", name); + let assert_as_ref_str = quote_spanned! {ty_span=> + struct #assert_ident where #ty: AsRef; + }; + + let ident = field.ident.as_ref().unwrap(); + let impl_ = match kind { + ImplType::Iter => quote! { + self.#ident + .iter() + .find(|repr| search.to_lowercase().starts_with(&repr.to_lowercase())) + .map(|repr| (self, repr.len())) + }, + ImplType::Single => quote! { + if search.starts_with(&self.#ident) { + Some((self, self.#ident.len())) + } else { + None + } + } + }; + + let gen = quote! { + #[allow(dead_code)] + #assert_as_ref_str + impl Searchable for #name { + fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)> { + #impl_ + } + } + }; + + TokenStream::from(gen) +} \ No newline at end of file diff --git a/src/lib/constants.rs b/src/lib/constants.rs index 900db8f..f4f4b2d 100644 --- a/src/lib/constants.rs +++ b/src/lib/constants.rs @@ -1,6 +1,9 @@ #![allow(clippy::non_ascii_literal)] -use super::representable::{get_by_repr, Representable}; +use macros::Searchable; +use super::representable::Searchable; + +use super::representable::get_by_repr; #[allow(clippy::upper_case_acronyms)] #[derive(PartialEq, Clone, Copy, Debug)] @@ -10,18 +13,15 @@ pub enum ConstantType { Tau, } +#[derive(Searchable)] pub struct Constant { pub kind: ConstantType, + + #[representation] pub repr: &'static [&'static str], pub value: f64, } -impl Representable for Constant { - fn repr(&self) -> &[&str] { - self.repr - } -} - static CONSTANTS: &[Constant] = &[ Constant { kind: ConstantType::PI, diff --git a/src/lib/operators.rs b/src/lib/operators.rs index 28c37a5..d749392 100644 --- a/src/lib/operators.rs +++ b/src/lib/operators.rs @@ -2,7 +2,10 @@ use rand::Rng; -use super::representable::{get_by_repr, Representable}; +use macros::Searchable; +use super::representable::Searchable; + +use super::representable::get_by_repr; #[derive(PartialEq, Clone, Copy, Debug)] pub enum OperatorType { @@ -27,21 +30,17 @@ pub enum OperatorType { const UNARY_OPERATORS: &[OperatorType] = &[OperatorType::Positive, OperatorType::Negative]; -impl Representable for OperatorType { - fn repr(&self) -> &'static [&'static str] { - Operator::by_type(*self).repr - } -} - #[derive(Clone, PartialEq, Copy)] pub enum Associativity { Left, Right, } -#[derive(Clone, Copy)] +#[derive(Searchable)] pub struct Operator { pub kind: OperatorType, + + #[representation] pub repr: &'static [&'static str], pub precedence: u8, pub associativity: Associativity, @@ -49,12 +48,6 @@ pub struct Operator { pub doit: fn(&[f64]) -> f64, } -impl Representable for Operator { - fn repr(&self) -> &[&str] { - self.repr - } -} - impl Operator { pub fn by_type(kind: OperatorType) -> &'static Self { OPERATORS.iter().find(|op| op.kind == kind).unwrap() @@ -66,7 +59,8 @@ impl Operator { Self::by_repr(repr).is_some() } pub fn unary(repr: &str) -> Option<(&OperatorType, usize)> { - get_by_repr(repr, UNARY_OPERATORS) + let ops = UNARY_OPERATORS.iter().map(|&uop| Self::by_type(uop)); + get_by_repr(repr, ops).map(|(op, idx)| (&op.kind, idx)) } } diff --git a/src/lib/representable.rs b/src/lib/representable.rs index 31e60fa..5121ab8 100644 --- a/src/lib/representable.rs +++ b/src/lib/representable.rs @@ -1,23 +1,26 @@ -pub trait Representable { - fn repr(&self) -> &[&str]; -} +// pub trait Representable { +// fn repr(&self) -> &[&str]; +// } pub trait Searchable { fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)>; } -impl Searchable for Repr { - fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)> { - self.repr() - .iter() - .find(|repr| search.to_lowercase().starts_with(&repr.to_lowercase())) - .map(|repr| (self, repr.len())) - } -} +// impl Searchable for Repr { +// fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)> { +// self.repr() +// .iter() +// .find(|repr| search.to_lowercase().starts_with(&repr.to_lowercase())) +// .map(|repr| (self, repr.len())) +// } +// } -pub(super) fn get_by_repr<'a, T: Searchable>( +pub(super) fn get_by_repr<'a, T, L>( search: &str, - list: &'a [T], -) -> Option<(&'a T, usize)> { - list.iter().find_map(|t| t.search(search)) + list: L, +) -> Option<(&'a T, usize)> +where T: Searchable, +L: IntoIterator +{ + list.into_iter().find_map(|t| t.search(search)) } diff --git a/src/lib/variables.rs b/src/lib/variables.rs index 3021950..aef8826 100644 --- a/src/lib/variables.rs +++ b/src/lib/variables.rs @@ -1,23 +1,16 @@ +use macros::Searchable; + use super::representable::{get_by_repr, Searchable}; -#[derive(Clone, Debug, PartialEq)] +#[derive(Searchable, Clone, Debug, PartialEq)] /// Represents a user definable variable pub struct Variable { + + #[representation] pub repr: String, pub value: f64, } -impl Searchable for Variable { - fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)> { - // Case sensitive - if search.starts_with(&self.repr) { - Some((self, self.repr.len())) - } else { - None - } - } -} - impl Variable { /// Searches for the first variable in `vars` that matches the representation given by the start of `text` /// * `text` - The string to search. Must start with the name of a variable (not a '$') but can From 65c216926e7b306a6c732cbc4d158d526c3b2312 Mon Sep 17 00:00:00 2001 From: George Lewis Date: Fri, 30 Apr 2021 21:11:52 -0400 Subject: [PATCH 02/10] lint --- src/lib/constants.rs | 2 +- src/lib/operators.rs | 2 +- src/lib/representable.rs | 10 ++++------ src/lib/variables.rs | 1 - 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/lib/constants.rs b/src/lib/constants.rs index f4f4b2d..548a444 100644 --- a/src/lib/constants.rs +++ b/src/lib/constants.rs @@ -1,7 +1,7 @@ #![allow(clippy::non_ascii_literal)] -use macros::Searchable; use super::representable::Searchable; +use macros::Searchable; use super::representable::get_by_repr; diff --git a/src/lib/operators.rs b/src/lib/operators.rs index d749392..e691128 100644 --- a/src/lib/operators.rs +++ b/src/lib/operators.rs @@ -2,8 +2,8 @@ use rand::Rng; -use macros::Searchable; use super::representable::Searchable; +use macros::Searchable; use super::representable::get_by_repr; diff --git a/src/lib/representable.rs b/src/lib/representable.rs index 5121ab8..d377d34 100644 --- a/src/lib/representable.rs +++ b/src/lib/representable.rs @@ -15,12 +15,10 @@ pub trait Searchable { // } // } -pub(super) fn get_by_repr<'a, T, L>( - search: &str, - list: L, -) -> Option<(&'a T, usize)> -where T: Searchable, -L: IntoIterator +pub(super) fn get_by_repr<'a, T, L>(search: &str, list: L) -> Option<(&'a T, usize)> +where + T: Searchable, + L: IntoIterator, { list.into_iter().find_map(|t| t.search(search)) } diff --git a/src/lib/variables.rs b/src/lib/variables.rs index aef8826..d3db7e3 100644 --- a/src/lib/variables.rs +++ b/src/lib/variables.rs @@ -5,7 +5,6 @@ use super::representable::{get_by_repr, Searchable}; #[derive(Searchable, Clone, Debug, PartialEq)] /// Represents a user definable variable pub struct Variable { - #[representation] pub repr: String, pub value: f64, From 2c34b848bfbf3ce7f9809ed07aedecbbfa7baacb Mon Sep 17 00:00:00 2001 From: George Lewis Date: Fri, 30 Apr 2021 21:15:57 -0400 Subject: [PATCH 03/10] delete representable and rename file --- src/lib/constants.rs | 4 ++-- src/lib/mod.rs | 2 +- src/lib/operators.rs | 4 ++-- src/lib/representable.rs | 24 ------------------------ src/lib/searchable.rs | 11 +++++++++++ src/lib/variables.rs | 2 +- 6 files changed, 17 insertions(+), 30 deletions(-) delete mode 100644 src/lib/representable.rs create mode 100644 src/lib/searchable.rs diff --git a/src/lib/constants.rs b/src/lib/constants.rs index 548a444..d18d438 100644 --- a/src/lib/constants.rs +++ b/src/lib/constants.rs @@ -1,9 +1,9 @@ #![allow(clippy::non_ascii_literal)] -use super::representable::Searchable; +use super::searchable::Searchable; use macros::Searchable; -use super::representable::get_by_repr; +use super::searchable::get_by_repr; #[allow(clippy::upper_case_acronyms)] #[derive(PartialEq, Clone, Copy, Debug)] diff --git a/src/lib/mod.rs b/src/lib/mod.rs index a840f4f..78d1a66 100644 --- a/src/lib/mod.rs +++ b/src/lib/mod.rs @@ -2,8 +2,8 @@ pub mod constants; pub mod errors; mod eval; pub mod operators; -mod representable; mod rpn; +mod searchable; mod tokenize; pub mod tokens; pub mod utils; diff --git a/src/lib/operators.rs b/src/lib/operators.rs index e691128..e3c5574 100644 --- a/src/lib/operators.rs +++ b/src/lib/operators.rs @@ -2,10 +2,10 @@ use rand::Rng; -use super::representable::Searchable; +use super::searchable::Searchable; use macros::Searchable; -use super::representable::get_by_repr; +use super::searchable::get_by_repr; #[derive(PartialEq, Clone, Copy, Debug)] pub enum OperatorType { diff --git a/src/lib/representable.rs b/src/lib/representable.rs deleted file mode 100644 index d377d34..0000000 --- a/src/lib/representable.rs +++ /dev/null @@ -1,24 +0,0 @@ -// pub trait Representable { -// fn repr(&self) -> &[&str]; -// } - -pub trait Searchable { - fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)>; -} - -// impl Searchable for Repr { -// fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)> { -// self.repr() -// .iter() -// .find(|repr| search.to_lowercase().starts_with(&repr.to_lowercase())) -// .map(|repr| (self, repr.len())) -// } -// } - -pub(super) fn get_by_repr<'a, T, L>(search: &str, list: L) -> Option<(&'a T, usize)> -where - T: Searchable, - L: IntoIterator, -{ - list.into_iter().find_map(|t| t.search(search)) -} diff --git a/src/lib/searchable.rs b/src/lib/searchable.rs new file mode 100644 index 0000000..2388ca8 --- /dev/null +++ b/src/lib/searchable.rs @@ -0,0 +1,11 @@ +pub trait Searchable { + fn search<'a>(&'a self, search: &str) -> Option<(&'a Self, usize)>; +} + +pub(super) fn get_by_repr<'a, T, L>(search: &str, list: L) -> Option<(&'a T, usize)> +where + T: Searchable, + L: IntoIterator, +{ + list.into_iter().find_map(|t| t.search(search)) +} diff --git a/src/lib/variables.rs b/src/lib/variables.rs index d3db7e3..8fc404a 100644 --- a/src/lib/variables.rs +++ b/src/lib/variables.rs @@ -1,6 +1,6 @@ use macros::Searchable; -use super::representable::{get_by_repr, Searchable}; +use super::searchable::{get_by_repr, Searchable}; #[derive(Searchable, Clone, Debug, PartialEq)] /// Represents a user definable variable From 82f5fd21322c18ac2160b5f542c87329c06384b0 Mon Sep 17 00:00:00 2001 From: George Lewis Date: Fri, 30 Apr 2021 21:18:21 -0400 Subject: [PATCH 04/10] rename memer --- src/lib/tokens.rs | 2 +- src/lib/variables.rs | 2 +- src/main.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib/tokens.rs b/src/lib/tokens.rs index ee89ad4..73c6d64 100644 --- a/src/lib/tokens.rs +++ b/src/lib/tokens.rs @@ -66,7 +66,7 @@ impl Token<'_> { ParenType::Right => ')'.to_string(), }, Self::Constant { kind } => Constant::by_type(*kind).repr[0].to_string(), - Self::Variable { inner } => format!("${}", inner.repr), + Self::Variable { inner } => format!("${}", inner.name), } } } diff --git a/src/lib/variables.rs b/src/lib/variables.rs index 8fc404a..9bcdc39 100644 --- a/src/lib/variables.rs +++ b/src/lib/variables.rs @@ -6,7 +6,7 @@ use super::searchable::{get_by_repr, Searchable}; /// Represents a user definable variable pub struct Variable { #[representation] - pub repr: String, + pub name: String, pub value: f64, } diff --git a/src/main.rs b/src/main.rs index 24c9d90..c372bd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -160,7 +160,7 @@ fn format_vars(vars: &[Variable]) -> String { .map(|var| { format!( "[ ${} => {} ]", - var.repr.green().bold(), + var.name.green().bold(), format!("{:.3}", var.value).blue() ) }) @@ -206,7 +206,7 @@ fn assign_var_command(input: &str, vars: &mut Vec) -> Result, repr: &str, value: f64) { - let cmp = |var: &Variable| repr.cmp(&var.repr); + let cmp = |var: &Variable| repr.cmp(&var.name); let search = vars.binary_search_by(cmp); match search { Ok(idx) => { @@ -214,7 +214,7 @@ fn assign_var(vars: &mut Vec, repr: &str, value: f64) { } Err(idx) => { let var = Variable { - repr: repr.to_string(), + name: repr.to_string(), value, }; vars.insert(idx, var); @@ -698,11 +698,11 @@ mod tests { fn test_vars() { let test_vars = vec![ Variable { - repr: String::from('v'), + name: String::from('v'), value: 5.0, }, Variable { - repr: String::from("pi"), + name: String::from("pi"), value: 7.0, }, ]; From 354fa52aa2b9346eb03da57c92b30ce6aa3f6a92 Mon Sep 17 00:00:00 2001 From: George Lewis Date: Fri, 30 Apr 2021 21:30:30 -0400 Subject: [PATCH 05/10] simplify cargo toml --- Cargo.lock | 2 +- macros/Cargo.toml | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94dc86a..a4e332e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,7 +155,7 @@ dependencies = [ [[package]] name = "macros" -version = "0.1.0" +version = "0.0.0" dependencies = [ "quote", "syn", diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 95ce1aa..8d8106c 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -1,11 +1,8 @@ [package] name = "macros" -version = "0.1.0" -authors = ["George Lewis "] +version = "0.0.0" edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [lib] proc-macro = true From 3f0a2363ef80d40f75918c7f126a8494062b8e6e Mon Sep 17 00:00:00 2001 From: George Lewis Date: Fri, 30 Apr 2021 21:45:14 -0400 Subject: [PATCH 06/10] clean --- macros/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 4a09dfa..191982f 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -52,9 +52,10 @@ fn searchable_impl(ast: &DeriveInput) -> TokenStream { _ => return error!(ast.span(), "`Searchable` can only derive structs.") }; - let field = match field { - Some(f) => f, - None => return error!(ast.span(), "No `#[representable]` annotated member.") + let field = if let Some(field) = field { + field + } else { + return error!(ast.span(), "No `#[representable]` annotated member.") }; let ty_span = field.ty.span(); From 6eb3af8ecad62f6fedeb428f0dee797d0a14dacd Mon Sep 17 00:00:00 2001 From: George Lewis Date: Fri, 30 Apr 2021 21:46:07 -0400 Subject: [PATCH 07/10] improve names --- macros/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 191982f..2dab81c 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -45,8 +45,8 @@ fn searchable_impl(ast: &DeriveInput) -> TokenStream { // Find tagged field let field = match &ast.data { Data::Struct(struc) => { - struc.fields.iter().find(|f| { - f.attrs.iter().any(|a| a.path.is_ident("representation")) + struc.fields.iter().find(|fields| { + fields.attrs.iter().any(|attr| attr.path.is_ident("representation")) }) }, _ => return error!(ast.span(), "`Searchable` can only derive structs.") From c78a1870d359ca8a392c824ccd889b87a77908ab Mon Sep 17 00:00:00 2001 From: George Lewis Date: Sun, 2 May 2021 15:15:02 -0400 Subject: [PATCH 08/10] relocate --- src/lib/eval.rs | 2 +- src/lib/mod.rs | 14 +++++--------- src/lib/{ => model}/constants.rs | 0 src/lib/{ => model}/errors.rs | 0 src/lib/model/mod.rs | 6 ++++++ src/lib/{ => model}/operators.rs | 0 src/lib/{ => model}/representable.rs | 0 src/lib/{ => model}/tokens.rs | 0 src/lib/{ => model}/variables.rs | 0 src/lib/rpn.rs | 2 +- src/lib/tokenize.rs | 7 +++++-- src/main.rs | 23 ++++++++++++++--------- 12 files changed, 32 insertions(+), 22 deletions(-) rename src/lib/{ => model}/constants.rs (100%) rename src/lib/{ => model}/errors.rs (100%) create mode 100644 src/lib/model/mod.rs rename src/lib/{ => model}/operators.rs (100%) rename src/lib/{ => model}/representable.rs (100%) rename src/lib/{ => model}/tokens.rs (100%) rename src/lib/{ => model}/variables.rs (100%) diff --git a/src/lib/eval.rs b/src/lib/eval.rs index 4088a3b..9eaeda7 100644 --- a/src/lib/eval.rs +++ b/src/lib/eval.rs @@ -1,4 +1,4 @@ -use super::{constants::Constant, errors::Error, operators::Operator, tokens::Token}; +use super::model::{constants::Constant, errors::Error, operators::Operator, tokens::Token}; pub fn eval(tokens: &[Token]) -> Result { // We need a mutable copy of the tokens diff --git a/src/lib/mod.rs b/src/lib/mod.rs index a840f4f..d7b0e11 100644 --- a/src/lib/mod.rs +++ b/src/lib/mod.rs @@ -1,20 +1,16 @@ -pub mod constants; -pub mod errors; mod eval; -pub mod operators; -mod representable; mod rpn; mod tokenize; -pub mod tokens; + pub mod utils; -pub mod variables; -use errors::Error; +pub mod model; + use eval::eval; use rpn::rpn; use tokenize::tokenize; -use tokens::Token; -use variables::Variable; + +use self::model::{errors::Error, tokens::Token, variables::Variable}; pub fn doeval<'a>(string: &str, vars: &'a [Variable]) -> Result<(f64, Vec>), Error> { let tokens = tokenize(string, vars)?; diff --git a/src/lib/constants.rs b/src/lib/model/constants.rs similarity index 100% rename from src/lib/constants.rs rename to src/lib/model/constants.rs diff --git a/src/lib/errors.rs b/src/lib/model/errors.rs similarity index 100% rename from src/lib/errors.rs rename to src/lib/model/errors.rs diff --git a/src/lib/model/mod.rs b/src/lib/model/mod.rs new file mode 100644 index 0000000..cfdf656 --- /dev/null +++ b/src/lib/model/mod.rs @@ -0,0 +1,6 @@ +pub mod constants; +pub mod errors; +pub mod operators; +mod representable; +pub mod tokens; +pub mod variables; diff --git a/src/lib/operators.rs b/src/lib/model/operators.rs similarity index 100% rename from src/lib/operators.rs rename to src/lib/model/operators.rs diff --git a/src/lib/representable.rs b/src/lib/model/representable.rs similarity index 100% rename from src/lib/representable.rs rename to src/lib/model/representable.rs diff --git a/src/lib/tokens.rs b/src/lib/model/tokens.rs similarity index 100% rename from src/lib/tokens.rs rename to src/lib/model/tokens.rs diff --git a/src/lib/variables.rs b/src/lib/model/variables.rs similarity index 100% rename from src/lib/variables.rs rename to src/lib/model/variables.rs diff --git a/src/lib/rpn.rs b/src/lib/rpn.rs index 027c88b..380bcdb 100644 --- a/src/lib/rpn.rs +++ b/src/lib/rpn.rs @@ -1,4 +1,4 @@ -use super::{ +use super::model::{ errors::Error, operators::{Associativity, Operator}, tokens::{ParenType, Token}, diff --git a/src/lib/tokenize.rs b/src/lib/tokenize.rs index 9e56c1a..c7e0be1 100644 --- a/src/lib/tokenize.rs +++ b/src/lib/tokenize.rs @@ -1,6 +1,9 @@ use super::{ - constants::Constant, errors::Error, operators::*, tokens::ParenType, tokens::Token, utils, - variables::Variable, + model::{ + constants::Constant, errors::Error, operators::*, tokens::ParenType, tokens::Token, + variables::Variable, + }, + utils, }; #[derive(Clone, Debug, PartialEq)] diff --git a/src/main.rs b/src/main.rs index 24c9d90..b69b3cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,11 +13,16 @@ mod lib; use colored::*; use lazy_static::lazy_static; -use lib::doeval; -use lib::errors::Error; -use lib::operators::*; -use lib::tokens::*; -use lib::variables::Variable; +use lib::model::errors::Error; +use lib::{ + doeval, + model::{ + operators::{Associativity, Operator, OperatorType}, + tokens::{ParenType, Token}, + }, +}; + +use lib::model::variables::Variable; use lib::utils; use rustyline::Editor; @@ -458,11 +463,11 @@ mod tests { )] use crate::{ - lib::constants::*, lib::doeval, - lib::errors::Error, - lib::operators::*, - lib::{tokens::*, variables::Variable}, + lib::model::constants::*, + lib::model::errors::Error, + lib::model::operators::*, + lib::model::{tokens::*, variables::Variable}, stringify, }; From aa4804a0cf159b750ccb922c10938ae63d691a17 Mon Sep 17 00:00:00 2001 From: George Lewis Date: Sun, 2 May 2021 15:47:44 -0400 Subject: [PATCH 09/10] rearrange --- macros/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 2dab81c..a49630c 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -40,7 +40,6 @@ pub fn searchable_derive(ts: TokenStream) -> TokenStream { } fn searchable_impl(ast: &DeriveInput) -> TokenStream { - let name = &ast.ident; // Find tagged field let field = match &ast.data { @@ -66,6 +65,8 @@ fn searchable_impl(ast: &DeriveInput) -> TokenStream { Err(ts) => return ts }; + let name = &ast.ident; + // Enforce that the representation type has to be `AsRef` let assert_ident = format_ident!("{}AssertAsRefStr", name); let assert_as_ref_str = quote_spanned! {ty_span=> @@ -99,5 +100,5 @@ fn searchable_impl(ast: &DeriveInput) -> TokenStream { } }; - TokenStream::from(gen) + gen.into() } \ No newline at end of file From eb2eb363cd0065c7795ea423bd4417469dfecdde Mon Sep 17 00:00:00 2001 From: George Lewis Date: Sun, 2 May 2021 15:51:03 -0400 Subject: [PATCH 10/10] remove superfluous lifetimes --- src/lib/constants.rs | 2 +- src/lib/operators.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/constants.rs b/src/lib/constants.rs index d18d438..ec944e0 100644 --- a/src/lib/constants.rs +++ b/src/lib/constants.rs @@ -44,7 +44,7 @@ impl Constant { pub fn by_type(kind: ConstantType) -> &'static Self { CONSTANTS.iter().find(|c| c.kind == kind).unwrap() } - pub fn by_repr(repr: &str) -> Option<(&'static Self, usize)> { + pub fn by_repr(repr: &str) -> Option<(&Self, usize)> { get_by_repr(repr, CONSTANTS) } pub fn is(repr: &str) -> bool { diff --git a/src/lib/operators.rs b/src/lib/operators.rs index e3c5574..e9c51a0 100644 --- a/src/lib/operators.rs +++ b/src/lib/operators.rs @@ -52,7 +52,7 @@ impl Operator { pub fn by_type(kind: OperatorType) -> &'static Self { OPERATORS.iter().find(|op| op.kind == kind).unwrap() } - pub fn by_repr(repr: &str) -> Option<(&'static Self, usize)> { + pub fn by_repr(repr: &str) -> Option<(&Self, usize)> { get_by_repr(repr, OPERATORS) } pub fn is(repr: &str) -> bool {