From 8be210396558323eeec96247effa1591b4d49ea5 Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Sat, 11 May 2024 15:38:29 -0500 Subject: [PATCH 01/18] update Signed-off-by: Joe McCain III --- Cargo.toml | 2 +- actors/Cargo.toml | 3 +-- core/src/lib.rs | 1 + core/src/traits/ext/string.rs | 1 + core/src/traits/mod.rs | 3 ++- core/src/utils.rs | 2 ++ scsys/Cargo.toml | 8 ++++---- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f0aa3afc..b54956f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ keywords = ["blockchain", "primitives", "scsys"] license = "Apache-2.0" readme = "README.md" repository = "https://github.com/scattered-systems/scsys" -version = "0.2.2" +version = "0.2.3" [workspace] default-members = [ diff --git a/actors/Cargo.toml b/actors/Cargo.toml index 8f92755f..73946fc4 100644 --- a/actors/Cargo.toml +++ b/actors/Cargo.toml @@ -81,8 +81,7 @@ version = "0.3" [dependencies.scsys-core] default-features = false path = "../core" -version = "0.2.2" -# version = "0.2.2-nightly" +version = "0.2.3" [dependencies.serde] default-features = false diff --git a/core/src/lib.rs b/core/src/lib.rs index 3bb8ef12..e7e0cfcb 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -17,6 +17,7 @@ pub use self::{traits::prelude::*, types::prelude::*, utils::*}; pub(crate) mod macros; #[macro_use] pub(crate) mod seal; +#[cfg(any(feature = "std", feature = "alloc"))] pub(crate) mod utils; pub mod errors; diff --git a/core/src/traits/ext/string.rs b/core/src/traits/ext/string.rs index 8cb17bd1..82a0d522 100644 --- a/core/src/traits/ext/string.rs +++ b/core/src/traits/ext/string.rs @@ -14,6 +14,7 @@ impl StringExt for str { } } +#[cfg(feature = "std")] pub trait StringFmt { fn snake_case(&self) -> String; diff --git a/core/src/traits/mod.rs b/core/src/traits/mod.rs index a0a7ce7d..fb092e5f 100644 --- a/core/src/traits/mod.rs +++ b/core/src/traits/mod.rs @@ -27,8 +27,9 @@ pub trait IntoInner { } /// Interface for nameable data-structures +#[cfg(any(feature = "std", all(feature = "alloc", no_std)))] pub trait Name { - fn name(&self) -> String; + fn name(&self) -> &str; fn slug(&self) -> String { self.name().to_lowercase().replace(" ", "-") diff --git a/core/src/utils.rs b/core/src/utils.rs index e940e9fd..4c0a2b59 100644 --- a/core/src/utils.rs +++ b/core/src/utils.rs @@ -4,6 +4,8 @@ */ #[cfg(feature = "std")] pub use self::std_utils::*; +#[cfg(all(feature = "alloc", no_std))] +pub use alloc::string::String; /// Remove the first and last charecters of a string pub fn fnl_remove(data: impl ToString) -> String { diff --git a/scsys/Cargo.toml b/scsys/Cargo.toml index 1d03a37e..beffca38 100644 --- a/scsys/Cargo.toml +++ b/scsys/Cargo.toml @@ -98,21 +98,21 @@ required-features = ["derive"] [dependencies.scsys-actors] optional = true path = "../actors" -version = "0.2.2" +version = "0.2.3" [dependencies.scsys-core] path = "../core" -version = "0.2.2" +version = "0.2.3" [dependencies.scsys-derive] optional = true path = "../derive" -version = "0.2.2" +version = "0.2.3" [dependencies.scsys-macros] optional = true path = "../macros" -version = "0.2.2" +version = "0.2.3" [dev-dependencies] serde = { features = ["derive"], version = "1" } From be323f9523cf2a15282274834b31ea443987c759 Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Sun, 12 May 2024 08:54:19 -0500 Subject: [PATCH 02/18] update Signed-off-by: Joe McCain III --- .gitignore | 2 +- Cargo.toml | 4 +-- README.md | 35 +++++++++++----------- SECURITY.md | 14 ++++----- actors/tests/states.rs | 1 + core/Cargo.toml | 8 +++-- core/src/errors/error.rs | 38 ++++++++++++------------ core/src/errors/kinds.rs | 21 ++++++------- core/src/errors/mod.rs | 24 ++++----------- core/src/id/traits.rs | 32 ++++++++------------ core/src/lib.rs | 15 ++++++---- core/src/stores/kv.rs | 6 ++-- core/src/traits/appellation.rs | 34 ++++----------------- core/src/traits/classify.rs | 14 +++++---- core/src/traits/ext/string.rs | 4 ++- core/src/traits/mod.rs | 10 +++++-- core/src/types/direction.rs | 2 +- core/src/types/mod.rs | 54 ++++++++-------------------------- core/tests/errors.rs | 5 +++- core/tests/utils.rs | 1 + 20 files changed, 141 insertions(+), 183 deletions(-) create mode 100644 core/tests/utils.rs diff --git a/.gitignore b/.gitignore index d77e5ac3..68374cb2 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,5 @@ **/*.bk **/*.bk-* -*-log.* **/log.* +**/*log.* diff --git a/Cargo.toml b/Cargo.toml index b54956f7..0afa2f35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ debug = true debug-assertions = true incremental = true lto = false -panic = "unwind" +panic = "abort" rpath = false opt-level = 0 overflow-checks = true @@ -49,7 +49,7 @@ debug = false debug-assertions = false incremental = false lto = false -panic = "unwind" +panic = "abort" rpath = false opt-level = "z" overflow-checks = false diff --git a/README.md b/README.md index 06edfc6e..5d863a36 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,48 @@ # scsys -[![Clippy](https://github.com/Scattered-Systems/scsys/actions/workflows/clippy.yml/badge.svg)](https://github.com/Scattered-Systems/scsys/actions/workflows/clippy.yml) -[![Rust](https://github.com/Scattered-Systems/scsys/actions/workflows/rust.yml/badge.svg)](https://github.com/Scattered-Systems/scsys/actions/workflows/rust.yml) [![crates.io](https://img.shields.io/crates/v/scsys.svg)](https://crates.io/crates/scsys) [![docs](https://docs.rs/scsys/badge.svg)](https://docs.rs/scsys) +[![clippy](https://github.com/Scattered-Systems/scsys/actions/workflows/clippy.yml/badge.svg)](https://github.com/Scattered-Systems/scsys/actions/workflows/clippy.yml) +[![rust](https://github.com/Scattered-Systems/scsys/actions/workflows/rust.yml/badge.svg)](https://github.com/Scattered-Systems/scsys/actions/workflows/rust.yml) + *** -Welcome to scsys, this crate is dedicated to supporting the Scattered-Systems, DAO LLC ecosystem and inspires to be a well-designed wrapper around the standard Rust library that facilitates -the creation of dynamic, distributed systems. +Welcome to scsys, this library provides a set of primitives and utilities used throughout the ecosystem. + -## Getting Started +# Getting Started Use Rust's built-in package manager [crates](https://crates.io/crates/scsys) to install *scsys*. -### Building from the source +## Building from the source -#### _Clone the repository_ +### _Clone the repository_ ```bash git clone https://github.com/scattered-systems/scsys cd scsys ``` -#### *Build the workspace locally* +### _Build the workspace locally_ ```bash -cargo build -v --workspace +cargo build --all-features -v --workspace ``` -or +#### _Testing_ + +Automatically format and analyze the codebase before building then testing. ```bash -cargo build -r -v --workspace +cargo test --all-features -r -v --workspace ``` -#### *Testing* - -Automatically format and analyze the codebase before building then testing. - ```bash cargo test --all-features -r -v --workspace ``` -## Usage +# Usage ```rust use scsys::prelude::*; @@ -53,14 +52,14 @@ fn main() { } ``` -## Contributing +# Contributing Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate. -## License +# License - [Apache-2.0](https://choosealicense.com/licenses/apache-2.0/) - [MIT](https://choosealicense.com/licenses/mit/) diff --git a/SECURITY.md b/SECURITY.md index 0492b4a1..be7f677e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,17 +4,17 @@ This section is used to update intrested parties as to which versions are currently supported, with respect to the current version. -| Package | Current | Supported | -|---------|---------|-----------| -| scsys | 0.2.0 | <=0.2.0 | +| Version | Supported | +| :------ | :----------------- | +| 0.2.x | :white_check_mark: | +| 0.1.x | :x: | +| < 0.1 | :x: | ## Reporting a Vulnerability -If you discover a vulnerability feel free to email me at jo3mccain@scattered-systems.com or visit the -company [website](https://scsys.eth.limo) -for more information. +If you discover a vulnerability feel free to email me at support@scattered-systems.com or visit the company [website](https://scsys.eth.limo) for more information. ### _GitHub_ +- [Author](https://github.com/FL03) - [Company](https://github.com/scattered-systems) -- [Creator](https://github.com/FL03) diff --git a/actors/tests/states.rs b/actors/tests/states.rs index e69de29b..8b137891 100644 --- a/actors/tests/states.rs +++ b/actors/tests/states.rs @@ -0,0 +1 @@ + diff --git a/core/Cargo.toml b/core/Cargo.toml index d3d9fee1..d8499fc0 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -24,8 +24,6 @@ full = [ "serde", ] - - # *** [FF] Dependencies *** alloc = [ "rand?/alloc", @@ -63,6 +61,12 @@ crate-type = ["cdylib", "rlib"] doctest = true test = true +[[test]] +name = "errors" +required-features = ["std"] + + + [build-dependencies] [dependencies] diff --git a/core/src/errors/error.rs b/core/src/errors/error.rs index 1ec4d635..0589848d 100644 --- a/core/src/errors/error.rs +++ b/core/src/errors/error.rs @@ -4,18 +4,20 @@ */ use super::kinds::*; use crate::id::AtomicId; +#[cfg(all(feature = "alloc", no_std))] +use alloc::string::String; #[derive(Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub struct Error { +pub struct Error { id: AtomicId, - kind: ErrorKind, + kind: ErrorKind, message: String, ts: u128, } -impl Error { - pub fn new(kind: impl Into, message: impl ToString) -> Self { +impl Error { + pub fn new(kind: impl Into>, message: impl ToString) -> Self { Self { id: AtomicId::new(), kind: kind.into(), @@ -25,14 +27,14 @@ impl Error { } pub fn unknown(message: impl ToString) -> Self { - Self::new(ErrorKind::unknown(), message.to_string()) + Self::new(ErrorKind::::unknown(), message.to_string()) } pub fn id(&self) -> usize { *self.id } - pub fn kind(&self) -> &ErrorKind { + pub fn kind(&self) -> &ErrorKind { &self.kind } @@ -44,7 +46,7 @@ impl Error { self.ts } - pub fn set_kind(&mut self, kind: ErrorKind) { + pub fn set_kind(&mut self, kind: ErrorKind) { self.kind = kind; self.on_update(); } @@ -54,7 +56,7 @@ impl Error { self.on_update(); } - pub fn with_kind(mut self, kind: ErrorKind) -> Self { + pub fn with_kind(mut self, kind: ErrorKind) -> Self { self.kind = kind; self } @@ -69,11 +71,11 @@ impl Error { } } -unsafe impl Send for Error {} +unsafe impl Send for Error {} -unsafe impl Sync for Error {} +unsafe impl Sync for Error {} -impl core::fmt::Debug for Error { +impl core::fmt::Debug for Error { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!( f, @@ -85,7 +87,7 @@ impl core::fmt::Debug for Error { } } -impl core::fmt::Display for Error { +impl core::fmt::Display for Error { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!( f, @@ -98,10 +100,10 @@ impl core::fmt::Display for Error { } #[cfg(feature = "std")] -impl std::error::Error for Error {} +impl std::error::Error for Error {} -impl From for Error { - fn from(kind: ErrorKind) -> Self { +impl From> for Error { + fn from(kind: ErrorKind) -> Self { Self::new(kind, String::new()) } } @@ -121,21 +123,21 @@ macro_rules! impl_error_from { )* }; (@impl $variant:ident($($n:ident)::*): $from:ty) => { - impl From<$from> for Error { + impl From<$from> for Error { fn from(err: $from) -> Self { Self::new(ErrorKind::$variant($($n)::*(err.into())), err.to_string()) } } }; (@impl $variant:ident<$n:path>: $from:ty) => { - impl From<$from> for Error { + impl From<$from> for Error { fn from(err: $from) -> Self { Self::new(ErrorKind::$variant($n), err.to_string()) } } }; (@impl $variant:ident: $from:ty) => { - impl From<$from> for Error { + impl From<$from> for Error { fn from(err: $from) -> Self { Self::new(ErrorKind::$variant, err.to_string()) } diff --git a/core/src/errors/kinds.rs b/core/src/errors/kinds.rs index 3e40202b..a4721b65 100644 --- a/core/src/errors/kinds.rs +++ b/core/src/errors/kinds.rs @@ -2,6 +2,8 @@ Appellation: kinds Contrib: FL03 */ +#[cfg(all(feature = "alloc", no_std))] +use alloc::string::String; use smart_default::SmartDefault; use strum::{AsRefStr, Display, EnumCount, EnumIs, EnumIter, VariantNames}; @@ -41,11 +43,11 @@ where )] #[non_exhaustive] #[strum(serialize_all = "lowercase")] -pub enum ErrorKind { +pub enum ErrorKind { Async, Connection, #[default] - Error(ExternalError), + Error(ExternalError), Execution, IO, Operation(OperationalError), @@ -55,8 +57,8 @@ pub enum ErrorKind { Syntax, } -impl ErrorKind { - pub fn custom(error: impl ToString) -> Self { +impl ErrorKind { + pub fn custom(error: T) -> Self { Self::Error(ExternalError::custom(error)) } @@ -77,7 +79,6 @@ impl ErrorKind { Display, EnumCount, EnumIs, - EnumIter, Eq, Hash, Ord, @@ -87,15 +88,15 @@ impl ErrorKind { VariantNames, )] #[strum(serialize_all = "lowercase")] -pub enum ExternalError { - Custom(String), +pub enum ExternalError { + Custom(T), #[default] Unknown, } -impl ExternalError { - pub fn custom(error: impl ToString) -> Self { - Self::Custom(error.to_string()) +impl ExternalError { + pub fn custom(error: T) -> Self { + Self::Custom(error) } pub fn unknown() -> Self { diff --git a/core/src/errors/mod.rs b/core/src/errors/mod.rs index bbb32b74..853e78ce 100644 --- a/core/src/errors/mod.rs +++ b/core/src/errors/mod.rs @@ -10,23 +10,11 @@ pub use self::{error::*, kinds::*}; pub(crate) mod error; pub(crate) mod kinds; -#[cfg(test)] -mod tests { - use super::*; +/// A type alias for [core::result::Result] that employs the [crate::errors::Error] type +pub type Result = core::result::Result; - #[test] - fn test_error() { - let msg = "test"; - let err = Error::new(ErrorKind::custom("custom"), msg.to_string()); - assert_eq!(err.kind(), &ErrorKind::custom("custom")); - } - - #[test] - #[cfg(feature = "serde")] - fn test_error_serde() { - let err = Error::new(ErrorKind::custom("custom"), "test".to_string()); - let json = serde_json::to_value(&err).unwrap(); - let err2: Error = serde_json::from_value(json).unwrap(); - assert_eq!(err, err2); - } +pub(crate) mod prelude { + pub use super::error::Error; + pub use super::kinds::*; + pub use super::Result; } diff --git a/core/src/id/traits.rs b/core/src/id/traits.rs index d22f1732..9e3ae1c1 100644 --- a/core/src/id/traits.rs +++ b/core/src/id/traits.rs @@ -2,10 +2,12 @@ Appellation: traits Contrib: FL03 */ +#[cfg(all(feature = "alloc", no_std))] +use alloc::string::{String, ToString}; use core::borrow::Borrow; /// An `Identifier` is a type that can be used as an identifier -pub trait Identifier: ToString { +pub trait Identifier { private!(); } @@ -21,18 +23,10 @@ where fn get(&self) -> &Self::Item; } -pub trait Identifiable -where - Q: Identifier, -{ - type Item: Id; - - fn get(&self) -> &Self::Item; -} - +#[cfg(any(all(feature = "alloc", no_std), feature = "std"))] pub trait IdentifierExt: Identifier where - Self: Copy + Eq + Ord + core::hash::Hash, + Self: Copy + Eq + Ord + ToString + core::hash::Hash, { } @@ -42,12 +36,6 @@ where { } -pub trait IntoId { - type Id: Identifier; - - fn into_id(self) -> Self::Id; -} - pub trait Identify { type Id: Identifier; @@ -59,7 +47,7 @@ pub trait IdentifyMut: Identify { } /* - *********** impls *********** + ************* Implementations ************* */ impl Id for S where @@ -86,7 +74,8 @@ where impl HashId for Id where Id: Eq + Identifier + core::hash::Hash {} -impl IdentifierExt for Id where Id: Copy + Eq + Identifier + Ord + core::hash::Hash {} +#[cfg(any(all(feature = "alloc", no_std), feature = "std"))] +impl IdentifierExt for Id where Id: Copy + Eq + Identifier + Ord + ToString + core::hash::Hash {} macro_rules! identifier { ($($t:ty),*) => { @@ -102,4 +91,7 @@ macro_rules! identifier { } identifier!(f32, f64, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize); -identifier!(bool, char, &str, String); +identifier!(bool, char, &str); + +#[cfg(any(feature = "alloc", feature = "std"))] +identifier!(String); diff --git a/core/src/lib.rs b/core/src/lib.rs index e7e0cfcb..570510bf 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -10,8 +10,12 @@ #[cfg(feature = "alloc")] extern crate alloc; -#[doc(inline)] -pub use self::{traits::prelude::*, types::prelude::*, utils::*}; +pub use self::{traits::prelude::*, types::prelude::*}; + +#[cfg(any(feature = "std", feature = "alloc"))] +pub use self::errors::{Error, ErrorKind, Result}; +#[cfg(any(feature = "std", feature = "alloc"))] +pub use self::utils::*; #[macro_use] pub(crate) mod macros; @@ -20,6 +24,7 @@ pub(crate) mod seal; #[cfg(any(feature = "std", feature = "alloc"))] pub(crate) mod utils; +#[cfg(any(feature = "std", feature = "alloc"))] pub mod errors; #[cfg(any(feature = "std", feature = "alloc"))] pub mod hkt; @@ -32,13 +37,13 @@ pub mod traits; pub mod types; pub mod prelude { - pub use crate::errors::*; - pub use crate::hkt::prelude::*; pub use crate::id::prelude::*; pub use crate::stores::prelude::*; pub use crate::sync::prelude::*; + #[cfg(feature = "std")] pub use crate::time::*; pub use crate::traits::prelude::*; pub use crate::types::prelude::*; - pub use crate::utils::*; + #[cfg(any(feature = "std", feature = "alloc"))] + pub use crate::{errors::prelude::*, hkt::prelude::*, utils::*}; } diff --git a/core/src/stores/kv.rs b/core/src/stores/kv.rs index 40b0c498..85c00208 100644 --- a/core/src/stores/kv.rs +++ b/core/src/stores/kv.rs @@ -2,9 +2,9 @@ Appellation: store Contrib: FL03 */ -#[cfg(no_std)] +#[cfg(all(feature = "alloc", no_std))] use alloc::collections::{btree_map, BTreeMap}; -#[cfg(not(no_std))] +#[cfg(feature = "std")] use std::collections::{btree_map, BTreeMap}; pub trait Entry<'a> { @@ -80,7 +80,9 @@ macro_rules! impl_store { }; } +#[cfg(any(feature = "alloc", feature = "std"))] impl_entry!(btree_map where K: Ord); +#[cfg(any(feature = "alloc", feature = "std"))] impl_store!(BTreeMap, where K: Ord); #[cfg(feature = "std")] diff --git a/core/src/traits/appellation.rs b/core/src/traits/appellation.rs index 7d306417..cefeb474 100644 --- a/core/src/traits/appellation.rs +++ b/core/src/traits/appellation.rs @@ -2,7 +2,10 @@ Appellation: appellation Contrib: FL03 */ +#![cfg(any(feature = "std", all(feature = "alloc", no_std)))] use crate::prelude::{Classifier, Identifier}; +#[cfg(all(feature = "alloc", no_std))] +use alloc::string::String; /// An appellation is considered to be a name or title that is used to identify an object. /// For our purposes, an `Appellation` is a type that is used to identify an object in a computational space. @@ -23,34 +26,9 @@ pub trait Appellation { } } -pub trait FromAppellation -where - Cls: Classifier, - Id: Identifier, -{ - fn from_appellation(appellation: impl Appellation) -> Self; -} - -pub trait TryFromAppellation -where - Cls: Classifier, - Id: Identifier, - Self: Sized, -{ - type Error; - fn try_from_appellation( - appellation: impl Appellation, - ) -> Result; -} - -pub trait IntoAppellation -where - Cls: Classifier, - Id: Identifier, -{ - fn into_appellation(self) -> dyn Appellation; -} - +/* + ************* Implementations ************* +*/ impl Appellation for (Cls, Id, T) where Cls: Classifier, diff --git a/core/src/traits/classify.rs b/core/src/traits/classify.rs index 1279ffa0..eea9a4d9 100644 --- a/core/src/traits/classify.rs +++ b/core/src/traits/classify.rs @@ -2,6 +2,9 @@ Appellation: classify Contrib: FL03 */ +#[cfg(all(feature = "alloc", no_std))] +use alloc::string::String; + /// Interface for classifiable objects pub trait Classifiable { type Class: Classifier; @@ -12,10 +15,10 @@ pub trait Classifiable { /// Denotes an object that may be used as a classifier pub trait Classifier {} -macro_rules! impl_classifier { +macro_rules! classifier { ($($t:ty),*) => { $( - impl_classifier!(@loop $t); + classifier!(@loop $t); )* }; (@loop $t:ty) => { @@ -23,6 +26,7 @@ macro_rules! impl_classifier { }; } -impl_classifier!( - f32, f64, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, &str, String, char -); +classifier!(f32, f64, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, &str, char); + +#[cfg(any(feature = "alloc", feature = "std"))] +classifier!(String); diff --git a/core/src/traits/ext/string.rs b/core/src/traits/ext/string.rs index 82a0d522..d3eb5587 100644 --- a/core/src/traits/ext/string.rs +++ b/core/src/traits/ext/string.rs @@ -2,6 +2,9 @@ Appellation: string Contrib: FL03 */ +#![cfg(any(feature = "std", all(feature = "alloc", no_std)))] +#[cfg(all(feature = "alloc", no_std))] +use alloc::string::String; pub trait StringExt { /// Remove the first and last charecters of a string @@ -14,7 +17,6 @@ impl StringExt for str { } } -#[cfg(feature = "std")] pub trait StringFmt { fn snake_case(&self) -> String; diff --git a/core/src/traits/mod.rs b/core/src/traits/mod.rs index fb092e5f..95aa7a8a 100644 --- a/core/src/traits/mod.rs +++ b/core/src/traits/mod.rs @@ -1,8 +1,8 @@ /* - Appellation: specs + Appellation: traits Contrib: FL03 */ -pub use self::{appellation::*, classify::*, ext::prelude::*}; +pub use self::prelude::*; pub mod appellation; pub mod classify; @@ -15,6 +15,7 @@ pub mod ext { pub(crate) mod prelude { pub use super::slice::*; + #[cfg(any(feature = "alloc", feature = "std"))] pub use super::string::*; } } @@ -37,8 +38,11 @@ pub trait Name { } pub(crate) mod prelude { + #[cfg(any(feature = "alloc", feature = "std"))] pub use super::appellation::*; pub use super::classify::*; pub use super::ext::prelude::*; - pub use super::{IntoInner, Name}; + pub use super::IntoInner; + #[cfg(any(feature = "alloc", feature = "std"))] + pub use super::Name; } diff --git a/core/src/types/direction.rs b/core/src/types/direction.rs index ba5a84a5..bced3aff 100644 --- a/core/src/types/direction.rs +++ b/core/src/types/direction.rs @@ -56,7 +56,7 @@ impl Direction { #[cfg(test)] mod tests { use super::*; - use std::str::FromStr; + use core::str::FromStr; #[test] fn test_direction() { diff --git a/core/src/types/mod.rs b/core/src/types/mod.rs index 2b2de35c..81388f03 100644 --- a/core/src/types/mod.rs +++ b/core/src/types/mod.rs @@ -2,17 +2,23 @@ Appellation: types Contrib: FL03 */ - +pub use self::direction::Direction; +#[cfg(any(feature = "alloc", feature = "std"))] +pub use self::rustic::*; #[cfg(feature = "std")] pub use self::std_types::*; -pub use self::{direction::Direction, utils::*}; pub mod direction; -pub type BoxAny = Box; +#[cfg(any(feature = "alloc", feature = "std"))] +mod rustic { + #[cfg(all(feature = "alloc", no_std))] + use alloc::boxed::Box; + #[cfg(feature = "std")] + use std::boxed::Box; -/// A type alias for [core::result::Result] that employs the [crate::errors::Error] type -pub type Result = core::result::Result; + pub type BoxAny = Box; +} #[cfg(feature = "std")] mod std_types { @@ -32,44 +38,10 @@ mod std_types { pub type IOResult = std::io::Result; } -pub(crate) mod utils { - use core::any::{Any, TypeId}; - use core::str::FromStr; - - /// Checks to see if the input is a string - pub fn is_string(_s: &T) -> bool { - TypeId::of::() == TypeId::of::() - } - /// Simple function wrapper evaluating the claim that the given information is of type f64 - pub fn is_float(_val: &T) -> bool - where - T: Any + ?Sized, - { - TypeId::of::() == TypeId::of::() - } - - /// Simple function wrapper evaluating the claim that the given information is of type f64 - pub fn is_str_float(data: &T) -> bool { - f64::from_str(&data.to_string()).is_ok() - } -} - pub(crate) mod prelude { pub use super::direction::Direction; + #[cfg(any(feature = "alloc", feature = "std"))] + pub use super::rustic::*; #[cfg(feature = "std")] pub use super::std_types::*; - pub use super::utils::*; - pub use super::{BoxAny, Result}; -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_is_string() { - let s = "hello"; - assert!(!is_string(&s)); - assert!(is_string(&s.to_string())) - } } diff --git a/core/tests/errors.rs b/core/tests/errors.rs index b3b6cfaf..69461fc9 100644 --- a/core/tests/errors.rs +++ b/core/tests/errors.rs @@ -16,7 +16,10 @@ fn test_error() { #[test] #[cfg(feature = "serde")] fn test_error_serde() { - let err = Error::new(ErrorKind::custom("custom"), "test".to_string()); + let kind = ErrorKind::custom("custom".to_string()); + let message = "test"; + + let err = Error::new(kind, message); let json = serde_json::to_value(&err).unwrap(); let err2: Error = serde_json::from_value(json).unwrap(); assert_eq!(err, err2); diff --git a/core/tests/utils.rs b/core/tests/utils.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/core/tests/utils.rs @@ -0,0 +1 @@ + From 21f76b7fc420a328b19733ce21484d6b5f24846f Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Sun, 12 May 2024 08:55:43 -0500 Subject: [PATCH 03/18] update Signed-off-by: Joe McCain III --- SECURITY.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index be7f677e..a5d6c84d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -14,7 +14,7 @@ This section is used to update intrested parties as to which versions are curren If you discover a vulnerability feel free to email me at support@scattered-systems.com or visit the company [website](https://scsys.eth.limo) for more information. -### _GitHub_ +### GitHub -- [Author](https://github.com/FL03) -- [Company](https://github.com/scattered-systems) +- [FL03](https://github.com/FL03) +- [Scattered-Systems](https://github.com/scattered-systems) From 2d5bccf83858e1d353d5520c571ba9f5daf89aaf Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Fri, 24 May 2024 03:39:37 -0500 Subject: [PATCH 04/18] update Signed-off-by: Joe McCain III --- Cargo.toml | 1 + core/Cargo.toml | 7 ++++-- core/src/traits/adjust.rs | 45 +++++++++++++++++++++++++++++++++++++++ core/src/traits/dtype.rs | 19 +++++++++++++++++ core/src/traits/mod.rs | 6 ++++++ core/src/traits/toggle.rs | 37 ++++++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 core/src/traits/adjust.rs create mode 100644 core/src/traits/dtype.rs create mode 100644 core/src/traits/toggle.rs diff --git a/Cargo.toml b/Cargo.toml index 0afa2f35..90946986 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ members = [ resolver = "2" [workspace.dependencies] +num = { default-features = false, version = "0.4" } paste = "1" smart-default = "0.7" strum = { default-features = false, features = ["derive"], version = "0.26" } diff --git a/core/Cargo.toml b/core/Cargo.toml index d8499fc0..697614a8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -26,12 +26,14 @@ full = [ # *** [FF] Dependencies *** alloc = [ + "num/alloc", "rand?/alloc", "serde?/alloc", ] rand = [ "dep:rand", + "num/rand", ] serde = [ @@ -40,11 +42,13 @@ serde = [ ] serde-ext = [ + "num/serde", "rand?/serde1", ] # *** [FF] Environment(s) *** std = [ + "num/std", "rand?/std", "rand?/std_rng", "serde?/std", @@ -65,12 +69,11 @@ test = true name = "errors" required-features = ["std"] - - [build-dependencies] [dependencies] glob = "0.3" +num.workspace = true smart-default.workspace = true strum.workspace = true diff --git a/core/src/traits/adjust.rs b/core/src/traits/adjust.rs new file mode 100644 index 00000000..ee240abf --- /dev/null +++ b/core/src/traits/adjust.rs @@ -0,0 +1,45 @@ +/* + Appellation: adjust + Contrib: FL03 +*/ +use core::ops::{Add, Sub}; +use num::traits::One; + +pub trait Adjust { + type Output; + + fn adjust(&mut self, adjust: T) -> Self::Output; +} + +/// `Decrement` is a trait describing the ability to decrement a value. +/// +pub trait Decrement { + type Output; + + fn dec(&self) -> Self::Output; +} + +pub trait Increment { + type Output; + + fn inc(&self) -> Self::Output; +} + +/* + ******** implementations ******** +*/ +impl Decrement for S where S: One, for<'a> &'a S: Sub { + type Output = T; + + fn dec(&self) -> Self::Output { + self - S::one() + } +} + +impl Increment for S where S: One, for<'a> &'a S: Add { + type Output = T; + + fn inc(&self) -> Self::Output { + self + S::one() + } +} \ No newline at end of file diff --git a/core/src/traits/dtype.rs b/core/src/traits/dtype.rs new file mode 100644 index 00000000..c8cda2db --- /dev/null +++ b/core/src/traits/dtype.rs @@ -0,0 +1,19 @@ +/* + Appellation: dtype + Contrib: FL03 +*/ + +pub trait OfType { + fn of() -> bool + where + T: 'static, + Self: 'static, + { + core::any::TypeId::of::() == core::any::TypeId::of::() + } +} + +/* + ************* Implementations ************* +*/ +impl OfType for T {} \ No newline at end of file diff --git a/core/src/traits/mod.rs b/core/src/traits/mod.rs index 95aa7a8a..52ba2fe1 100644 --- a/core/src/traits/mod.rs +++ b/core/src/traits/mod.rs @@ -4,8 +4,11 @@ */ pub use self::prelude::*; +pub mod adjust; pub mod appellation; pub mod classify; +pub mod dtype; +pub mod toggle; pub mod ext { pub use self::prelude::*; @@ -38,10 +41,13 @@ pub trait Name { } pub(crate) mod prelude { + pub use super::adjust::*; #[cfg(any(feature = "alloc", feature = "std"))] pub use super::appellation::*; pub use super::classify::*; + pub use super::dtype::*; pub use super::ext::prelude::*; + pub use super::toggle::*; pub use super::IntoInner; #[cfg(any(feature = "alloc", feature = "std"))] pub use super::Name; diff --git a/core/src/traits/toggle.rs b/core/src/traits/toggle.rs new file mode 100644 index 00000000..32705051 --- /dev/null +++ b/core/src/traits/toggle.rs @@ -0,0 +1,37 @@ +/* + Appellation: toggle + Contrib: FL03 +*/ + +pub trait Toggle: 'static {} + +/* + ************* Implementations ************* +*/ + +macro_rules! impl_toggle { + ($($scope:ident$(<$T:ident>)?),* $(,)?) => { + $(impl_toggle!(@impl $scope$(<$T>)?);)* + }; + (@impl $scope:ident$(<$T:ident>)?) => { + impl$(<$T>)? Toggle for $scope$(<$T> where $T: 'static)? {} + }; +} + +impl_toggle!( + bool, + char, + i8, + i16, + i32, + i64, + i128, + isize, + u8, + u16, + u32, + u64, + u128, + usize, + Option +); From 5124647c96111fc59168038a35055dfe2bed0a16 Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Fri, 24 May 2024 03:42:52 -0500 Subject: [PATCH 05/18] update Signed-off-by: Joe McCain III --- .github/ISSUE_TEMPLATE/tracking.md | 18 ++++++++++++ core/src/macros.rs | 3 ++ core/src/macros/builder.rs | 47 ++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/tracking.md create mode 100644 core/src/macros/builder.rs diff --git a/.github/ISSUE_TEMPLATE/tracking.md b/.github/ISSUE_TEMPLATE/tracking.md new file mode 100644 index 00000000..8c3eada7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tracking.md @@ -0,0 +1,18 @@ +--- +about: Create a new tracking issue to track the progress of a proposal or feature. +assignees: + - FL03 +labels: ['tracking'] +projects: + - '@scattered-systems/scsys:features' +name: Tracking Issue +title: 'Tracking Issue:' +--- + +**Describe the proposal or feature that this issue is tracking.** + +## Issues + +- [] + +## Pull Requests diff --git a/core/src/macros.rs b/core/src/macros.rs index f1e1266c..e9cbc50e 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -3,6 +3,9 @@ Contrib: FL03 */ +#[macro_use] +mod builder; + #[allow(unused_macros)] macro_rules! impl_fmt { ($name:ty: $($t:ident($($rest:tt)*)),*) => { diff --git a/core/src/macros/builder.rs b/core/src/macros/builder.rs new file mode 100644 index 00000000..8fba06d2 --- /dev/null +++ b/core/src/macros/builder.rs @@ -0,0 +1,47 @@ +/* + Appellation: builder + Contrib: FL03 +*/ + +#[macro_export] +macro_rules! builder { + ($(#[derive($($d:ident),+)])?$name:ident::<$inner:ty> {$($k:ident: $v:ty),* $(,)?}) => { + builder!(@loop builder: $name, derive: [$($($d),+)?], inner: $inner {$($k: $v),*}); + }; + ($(#[derive($($d:ident),+)])? $name:ident($inner:ty) {$($k:ident: $v:ty),* $(,)?}) => { + builder!(@loop builder: $name, derive: [$($($d),+)?], inner: $inner {$($k: $v),*}); + }; + (@loop builder: $name:ident, derive: [$($d:ident),* $(,)?], inner: $inner:ty {$($k:ident: $v:ty),* $(,)?}) => { + + #[derive(Default, $($d),*)] + pub struct $name { + inner: $inner, + } + + builder!(@impl builder: $name, inner: $inner {$($k: $v),*}); + }; + (@impl builder: $name:ident, inner: $inner:ty {$($k:ident: $v:ty),* $(,)?}) => { + impl $name { + pub fn new() -> Self { + Self { + inner: Default::default() + } + } + + pub fn from_inner(inner: $inner) -> Self { + Self { inner } + } + + pub fn build(self) -> $inner { + self.inner + } + + $( + pub fn $k(mut self, $k: $v) -> Self { + self.inner.$k = $k; + self + } + )* + } + }; +} From 0798d73d09ba029398d67d5c151c1f010452139c Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Tue, 28 May 2024 02:01:57 -0500 Subject: [PATCH 06/18] update Signed-off-by: Joe McCain III --- core/src/traits/adjust.rs | 16 ++++++++++++---- core/src/traits/dtype.rs | 28 ++++++++++++++++++++-------- core/src/traits/toggle.rs | 39 ++++++++++++--------------------------- core/src/utils.rs | 10 ++++++++++ 4 files changed, 54 insertions(+), 39 deletions(-) diff --git a/core/src/traits/adjust.rs b/core/src/traits/adjust.rs index ee240abf..edfaf848 100644 --- a/core/src/traits/adjust.rs +++ b/core/src/traits/adjust.rs @@ -12,7 +12,7 @@ pub trait Adjust { } /// `Decrement` is a trait describing the ability to decrement a value. -/// +/// pub trait Decrement { type Output; @@ -28,7 +28,11 @@ pub trait Increment { /* ******** implementations ******** */ -impl Decrement for S where S: One, for<'a> &'a S: Sub { +impl Decrement for S +where + S: One, + for<'a> &'a S: Sub, +{ type Output = T; fn dec(&self) -> Self::Output { @@ -36,10 +40,14 @@ impl Decrement for S where S: One, for<'a> &'a S: Sub { } } -impl Increment for S where S: One, for<'a> &'a S: Add { +impl Increment for S +where + S: One, + for<'a> &'a S: Add, +{ type Output = T; fn inc(&self) -> Self::Output { self + S::one() } -} \ No newline at end of file +} diff --git a/core/src/traits/dtype.rs b/core/src/traits/dtype.rs index c8cda2db..f43e1f84 100644 --- a/core/src/traits/dtype.rs +++ b/core/src/traits/dtype.rs @@ -2,18 +2,30 @@ Appellation: dtype Contrib: FL03 */ +use crate::type_of; +use core::any::{Any, TypeId}; -pub trait OfType { - fn of() -> bool - where - T: 'static, - Self: 'static, - { - core::any::TypeId::of::() == core::any::TypeId::of::() +/// [DType] provides additional information regarding the current type +pub trait DType: Any { + fn of() -> bool { + type_of::() } + + fn is(&self) -> bool { + type_of::() + } + + fn type_id(&self) -> TypeId { + Any::type_id(self) + } + + fn type_name() -> &'static str where T: ?Sized { + core::any::type_name::() + } + } /* ************* Implementations ************* */ -impl OfType for T {} \ No newline at end of file +impl DType for dyn Any {} diff --git a/core/src/traits/toggle.rs b/core/src/traits/toggle.rs index 32705051..ed2af06e 100644 --- a/core/src/traits/toggle.rs +++ b/core/src/traits/toggle.rs @@ -2,36 +2,21 @@ Appellation: toggle Contrib: FL03 */ +use core::any::Any; -pub trait Toggle: 'static {} +/// Typically, [TypeTag] is used for uninitaliziable `enums` with no variants +pub trait TypeTag: 'static { + fn is(&self) -> bool where T: Any + ?Sized { + crate::type_of::() + } +} + +pub trait BinaryTag: TypeTag { + const MODE: bool; +} /* ************* Implementations ************* */ -macro_rules! impl_toggle { - ($($scope:ident$(<$T:ident>)?),* $(,)?) => { - $(impl_toggle!(@impl $scope$(<$T>)?);)* - }; - (@impl $scope:ident$(<$T:ident>)?) => { - impl$(<$T>)? Toggle for $scope$(<$T> where $T: 'static)? {} - }; -} - -impl_toggle!( - bool, - char, - i8, - i16, - i32, - i64, - i128, - isize, - u8, - u16, - u32, - u64, - u128, - usize, - Option -); +impl TypeTag for T where T: 'static {} \ No newline at end of file diff --git a/core/src/utils.rs b/core/src/utils.rs index 4c0a2b59..52234562 100644 --- a/core/src/utils.rs +++ b/core/src/utils.rs @@ -2,11 +2,21 @@ Appellation: utils Contrib: FL03 */ +use core::any::{Any, TypeId}; #[cfg(feature = "std")] pub use self::std_utils::*; #[cfg(all(feature = "alloc", no_std))] pub use alloc::string::String; +/// Compare two types +pub fn type_of() -> bool +where + U: Any + ?Sized, + V: Any + ?Sized, +{ + TypeId::of::() == TypeId::of::() +} + /// Remove the first and last charecters of a string pub fn fnl_remove(data: impl ToString) -> String { let data = data.to_string(); From 30184ecbcb42ce4aa84ccb2b0652e032b488273f Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Tue, 28 May 2024 13:11:45 -0500 Subject: [PATCH 07/18] update Signed-off-by: Joe McCain III --- .github/ISSUE_TEMPLATE/tracking.md | 16 +-- Cargo.toml | 8 +- core/Cargo.toml | 18 ++-- core/src/errors/error.rs | 22 ++-- core/src/errors/kinds.rs | 156 +++++++++++++---------------- core/src/lib.rs | 9 +- core/src/name/casing.rs | 39 ++++++++ core/src/name/mod.rs | 15 +++ core/src/primitives.rs | 52 ++++++++++ core/src/seal.rs | 2 +- core/src/traits/dtype.rs | 29 +++++- core/src/traits/toggle.rs | 16 ++- core/src/types/mod.rs | 36 ------- core/src/utils.rs | 40 +------- core/src/utils/std_utils.rs | 37 +++++++ core/tests/errors.rs | 8 +- 16 files changed, 296 insertions(+), 207 deletions(-) create mode 100644 core/src/name/casing.rs create mode 100644 core/src/name/mod.rs create mode 100644 core/src/primitives.rs create mode 100644 core/src/utils/std_utils.rs diff --git a/.github/ISSUE_TEMPLATE/tracking.md b/.github/ISSUE_TEMPLATE/tracking.md index 8c3eada7..32a3eb4b 100644 --- a/.github/ISSUE_TEMPLATE/tracking.md +++ b/.github/ISSUE_TEMPLATE/tracking.md @@ -1,18 +1,22 @@ --- about: Create a new tracking issue to track the progress of a proposal or feature. -assignees: - - FL03 -labels: ['tracking'] -projects: - - '@scattered-systems/scsys:features' +assignees: [FL03] +labels: [ 'tracking' ] +projects: [ '@scattered-systems/scsys:features' ] name: Tracking Issue title: 'Tracking Issue:' --- -**Describe the proposal or feature that this issue is tracking.** +_Describe the issue(s) or feature being tracked..._ ## Issues - [] ## Pull Requests + +- [] + +## Resources + +_Include any relevant links or resources..._ diff --git a/Cargo.toml b/Cargo.toml index 90946986..bd3e8936 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,13 @@ [workspace.package] -authors = ["FL03 (https://github.com/FL03)", "Scattered-Systems (https://github.com/scattered-systems)"] +authors = ["FL03 ", "Scattered-Systems "] categories = [] description = "scsys is a collection of primitives and utilities for use throughout the ecosystem." edition = "2021" homepage = "https://github.com/scattered-systems/scsys/wiki" -keywords = ["blockchain", "primitives", "scsys"] +keywords = ["primitives", "scsys", "toolkit", "utilities"] license = "Apache-2.0" readme = "README.md" -repository = "https://github.com/scattered-systems/scsys" +repository = "https://github.com/scattered-systems/scsys.git" version = "0.2.3" [workspace] @@ -28,6 +28,8 @@ members = [ resolver = "2" [workspace.dependencies] +anyhow = "1" +lazy_static = "1" num = { default-features = false, version = "0.4" } paste = "1" smart-default = "0.7" diff --git a/core/Cargo.toml b/core/Cargo.toml index 697614a8..261fd506 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -24,7 +24,7 @@ full = [ "serde", ] -# *** [FF] Dependencies *** +# ******* [FF] Dependencies ******* alloc = [ "num/alloc", "rand?/alloc", @@ -46,7 +46,7 @@ serde-ext = [ "rand?/serde1", ] -# *** [FF] Environment(s) *** +# ******* [FF] Environment ******* std = [ "num/std", "rand?/std", @@ -57,7 +57,9 @@ std = [ wasi = [] -wasm = [] +wasm = [ + "getrandom/js", +] [lib] bench = false @@ -71,6 +73,10 @@ required-features = ["std"] [build-dependencies] +[dev-dependencies] +anyhow = "1" +serde_json = "1" + [dependencies] glob = "0.3" num.workspace = true @@ -88,14 +94,10 @@ features = ["derive"] optional = true version = "1" -[dev-dependencies] -anyhow = "1" -serde_json = "1" - [package.metadata.docs.rs] rustc-args = ["--cfg", "docsrs"] [target.wasm32-unknown-unknown.dependencies] -getrandom = { features = ["js"], version = "0.2" } +getrandom = "0.2" [target.wasm32-wasi] diff --git a/core/src/errors/error.rs b/core/src/errors/error.rs index 0589848d..852e6b3c 100644 --- a/core/src/errors/error.rs +++ b/core/src/errors/error.rs @@ -11,13 +11,13 @@ use alloc::string::String; #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct Error { id: AtomicId, - kind: ErrorKind, + kind: Errors, message: String, ts: u128, } impl Error { - pub fn new(kind: impl Into>, message: impl ToString) -> Self { + pub fn new(kind: impl Into>, message: impl ToString) -> Self { Self { id: AtomicId::new(), kind: kind.into(), @@ -27,14 +27,14 @@ impl Error { } pub fn unknown(message: impl ToString) -> Self { - Self::new(ErrorKind::::unknown(), message.to_string()) + Self::new(Errors::::unknown(), message.to_string()) } pub fn id(&self) -> usize { *self.id } - pub fn kind(&self) -> &ErrorKind { + pub fn kind(&self) -> &Errors { &self.kind } @@ -46,7 +46,7 @@ impl Error { self.ts } - pub fn set_kind(&mut self, kind: ErrorKind) { + pub fn set_kind(&mut self, kind: Errors) { self.kind = kind; self.on_update(); } @@ -56,7 +56,7 @@ impl Error { self.on_update(); } - pub fn with_kind(mut self, kind: ErrorKind) -> Self { + pub fn with_kind(mut self, kind: Errors) -> Self { self.kind = kind; self } @@ -102,8 +102,8 @@ impl core::fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} -impl From> for Error { - fn from(kind: ErrorKind) -> Self { +impl From> for Error { + fn from(kind: Errors) -> Self { Self::new(kind, String::new()) } } @@ -125,21 +125,21 @@ macro_rules! impl_error_from { (@impl $variant:ident($($n:ident)::*): $from:ty) => { impl From<$from> for Error { fn from(err: $from) -> Self { - Self::new(ErrorKind::$variant($($n)::*(err.into())), err.to_string()) + Self::new(Errors::$variant($($n)::*(err.into())), err.to_string()) } } }; (@impl $variant:ident<$n:path>: $from:ty) => { impl From<$from> for Error { fn from(err: $from) -> Self { - Self::new(ErrorKind::$variant($n), err.to_string()) + Self::new(Errors::$variant($n), err.to_string()) } } }; (@impl $variant:ident: $from:ty) => { impl From<$from> for Error { fn from(err: $from) -> Self { - Self::new(ErrorKind::$variant, err.to_string()) + Self::new(Errors::$variant, err.to_string()) } } }; diff --git a/core/src/errors/kinds.rs b/core/src/errors/kinds.rs index a4721b65..6f97f9f0 100644 --- a/core/src/errors/kinds.rs +++ b/core/src/errors/kinds.rs @@ -5,26 +5,13 @@ #[cfg(all(feature = "alloc", no_std))] use alloc::string::String; use smart_default::SmartDefault; -use strum::{AsRefStr, Display, EnumCount, EnumIs, EnumIter, VariantNames}; +use strum::{AsRefStr, Display, EnumCount, EnumIs, VariantNames}; -pub trait ErrorClass { +pub trait ErrorTy { fn name(&self) -> &str; } -#[derive(Clone)] -pub enum Errors -where - E: ErrorClass, -{ - Custom(E), - Unknown, -} -#[cfg_attr( - feature = "serde", - derive(serde::Deserialize, serde::Serialize,), - serde(rename_all = "lowercase", untagged) -)] #[derive( AsRefStr, Clone, @@ -32,7 +19,6 @@ where Display, EnumCount, EnumIs, - EnumIter, Eq, Hash, Ord, @@ -41,9 +27,14 @@ where SmartDefault, VariantNames, )] +#[cfg_attr( + feature = "serde", + derive(serde::Deserialize, serde::Serialize), + serde(rename_all = "lowercase", untagged) +)] #[non_exhaustive] #[strum(serialize_all = "lowercase")] -pub enum ErrorKind { +pub enum Errors { Async, Connection, #[default] @@ -57,7 +48,7 @@ pub enum ErrorKind { Syntax, } -impl ErrorKind { +impl Errors { pub fn custom(error: T) -> Self { Self::Error(ExternalError::custom(error)) } @@ -67,85 +58,42 @@ impl ErrorKind { } } -#[cfg_attr( - feature = "serde", - derive(serde::Deserialize, serde::Serialize), - serde(rename_all = "lowercase", untagged) -)] -#[derive( - AsRefStr, - Clone, - Debug, - Display, - EnumCount, - EnumIs, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - SmartDefault, - VariantNames, -)] -#[strum(serialize_all = "lowercase")] -pub enum ExternalError { - Custom(T), - #[default] - Unknown, -} -impl ExternalError { - pub fn custom(error: T) -> Self { - Self::Custom(error) - } - pub fn unknown() -> Self { - Self::Unknown - } -} -#[cfg_attr( - feature = "serde", - derive(serde::Deserialize, serde::Serialize), - serde(rename_all = "lowercase", untagged) -)] -#[derive( - AsRefStr, - Clone, - Debug, - Display, - EnumCount, - EnumIs, - EnumIter, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - SmartDefault, - VariantNames, -)] -#[non_exhaustive] -#[strum(serialize_all = "lowercase")] -pub enum OperationalError { - #[default] - Arithmetic, - System, -} -impl OperationalError { - pub fn arithmetic() -> Self { - Self::Arithmetic - } - pub fn system() -> Self { - Self::System - } +macro_rules! err { + ($name:ident $($rest:tt)*) => { + #[derive( + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + strum::AsRefStr, + strum::Display, + strum::EnumCount, + strum::EnumIs, + strum::VariantNames, + )] + #[cfg_attr( + feature = "serde", + derive(serde::Deserialize, serde::Serialize), + serde(rename_all = "lowercase", untagged) + )] + #[non_exhaustive] + #[strum(serialize_all = "lowercase")] + pub enum $name $($rest)* + }; } macro_rules! impl_kind_from { ($variant:ident, $kind:ident) => { - impl From<$kind> for ErrorKind { + impl From<$kind> for Errors { fn from(kind: $kind) -> Self { Self::$variant(kind) } @@ -158,5 +106,37 @@ macro_rules! impl_kind_from { }; } +err! { + OperationalError { + Arithmetic, + System, + } +} + +err! { + ExternalError { + Custom(T), + Unknown, + } +} + +impl ExternalError { + pub fn custom(error: T) -> Self { + Self::Custom(error) + } + + pub fn unknown() -> Self { + Self::Unknown + } +} + + +impl Default for ExternalError { + fn default() -> Self { + Self::Unknown + } +} + + impl_kind_from!(Error, ExternalError); impl_kind_from!(Operation, OperationalError); diff --git a/core/src/lib.rs b/core/src/lib.rs index 570510bf..7566f6ba 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -13,13 +13,15 @@ extern crate alloc; pub use self::{traits::prelude::*, types::prelude::*}; #[cfg(any(feature = "std", feature = "alloc"))] -pub use self::errors::{Error, ErrorKind, Result}; +pub use self::errors::{Error, Errors, Result}; #[cfg(any(feature = "std", feature = "alloc"))] -pub use self::utils::*; +pub use self::{primitives::*, utils::*}; #[macro_use] pub(crate) mod macros; #[macro_use] +pub(crate) mod primitives; +#[macro_use] pub(crate) mod seal; #[cfg(any(feature = "std", feature = "alloc"))] pub(crate) mod utils; @@ -29,6 +31,8 @@ pub mod errors; #[cfg(any(feature = "std", feature = "alloc"))] pub mod hkt; pub mod id; +#[doc(hidden)] +pub mod name; pub mod stores; pub mod sync; #[cfg(feature = "std")] @@ -38,6 +42,7 @@ pub mod types; pub mod prelude { pub use crate::id::prelude::*; + pub use crate::name::prelude::*; pub use crate::stores::prelude::*; pub use crate::sync::prelude::*; #[cfg(feature = "std")] diff --git a/core/src/name/casing.rs b/core/src/name/casing.rs new file mode 100644 index 00000000..cfae9ae9 --- /dev/null +++ b/core/src/name/casing.rs @@ -0,0 +1,39 @@ +/* + Appellation: convention + Contrib: FL03 +*/ +use strum::{ + AsRefStr, Display, EnumCount, EnumIs, EnumIter, EnumString, VariantArray, VariantNames, +}; + +#[derive( + AsRefStr, + Clone, + Copy, + Debug, + Display, + EnumCount, + EnumIs, + EnumIter, + EnumString, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + VariantArray, + VariantNames, +)] +#[cfg_attr( + feature = "serde", + derive(serde::Deserialize, serde::Serialize,), + serde(rename_all = "snake_case") +)] +#[repr(u8)] +#[strum(serialize_all = "snake_case")] +pub enum CaseType { + CamelCase, + KebabCase, + PascalCase, + SnakeCase, +} diff --git a/core/src/name/mod.rs b/core/src/name/mod.rs new file mode 100644 index 00000000..baae719e --- /dev/null +++ b/core/src/name/mod.rs @@ -0,0 +1,15 @@ +/* + Appellation: name + Contrib: FL03 +*/ +//! # Name +//! +//! This module works to implement various naming conventions and name-related primitives. + +pub use self::casing::*; + +pub(crate) mod casing; + +pub(crate) mod prelude { + pub use super::casing::CaseType; +} diff --git a/core/src/primitives.rs b/core/src/primitives.rs new file mode 100644 index 00000000..ae5d1cdb --- /dev/null +++ b/core/src/primitives.rs @@ -0,0 +1,52 @@ +/* + Appellation: primitives + Contrib: FL03 +*/ + +#[cfg(feature = "std")] +pub use self::std_types::*; + +#[cfg(feature = "std")] +mod std_types { + use std::sync::{Arc, Mutex}; + /// Type alias for async errors + pub type AsyncError = Box; + /// Type alias for async results + pub type AsyncResult = core::result::Result; + /// Type alias for a boxed error with send, sync, and static flags enabled + pub type BoxError = Box; + /// Type alias for the standard result used + pub type BoxResult = core::result::Result; + /// Type alias wrapping a locked, thread-safe structure with a [Mutex] in an [Arc] + pub type Locked = Arc>; + /// Type alias for [std::io::Result] + pub type IOResult = std::io::Result; +} + +#[allow(unused_imports)] +pub(crate) mod rs { + pub(crate) use core::*; + + #[cfg(all(feature = "alloc", no_std))] + pub(crate) use self::no_std::*; + #[cfg(feature = "std")] + pub(crate) use self::std_ty::*; + + #[cfg(feature = "alloc")] + pub(crate) mod no_std { + pub(crate) use alloc::boxed::{self, Box}; + pub(crate) use alloc::collections::{self, BTreeMap, BTreeSet}; + pub(crate) use alloc::string::{self, String, ToString}; + pub(crate) use alloc::sync::{self, Arc}; + pub(crate) use alloc::vec::{self, Vec}; + } + + #[cfg(feature = "std")] + pub(crate) mod std_ty { + pub(crate) use std::boxed::{self, Box}; + pub(crate) use std::collections::{self, BTreeMap, BTreeSet}; + pub(crate) use std::string::{self, String, ToString}; + pub(crate) use std::sync::{self, Arc}; + pub(crate) use std::vec::{self, Vec}; + } +} \ No newline at end of file diff --git a/core/src/seal.rs b/core/src/seal.rs index 6ffe5462..565ed319 100644 --- a/core/src/seal.rs +++ b/core/src/seal.rs @@ -1,5 +1,5 @@ /* - Appellation: seal + Appellation: seal Contrib: FL03 */ //! The public parts of this private module are used to create traits diff --git a/core/src/traits/dtype.rs b/core/src/traits/dtype.rs index f43e1f84..f56ffe29 100644 --- a/core/src/traits/dtype.rs +++ b/core/src/traits/dtype.rs @@ -5,8 +5,30 @@ use crate::type_of; use core::any::{Any, TypeId}; +pub trait IsType: 'static { + fn of() -> bool { + type_of::() + } + + fn is(&self) -> bool { + type_of::() + } +} + /// [DType] provides additional information regarding the current type pub trait DType: Any { + + fn type_id(&self) -> TypeId { + Any::type_id(self) + } + + fn type_name(&self) -> &'static str { + core::any::type_name::() + } + +} + +pub trait DTypeExt: DType { fn of() -> bool { type_of::() } @@ -22,10 +44,13 @@ pub trait DType: Any { fn type_name() -> &'static str where T: ?Sized { core::any::type_name::() } - } /* ************* Implementations ************* */ -impl DType for dyn Any {} +impl IsType for T {} + +impl dyn DType { + +} diff --git a/core/src/traits/toggle.rs b/core/src/traits/toggle.rs index ed2af06e..5ea36505 100644 --- a/core/src/traits/toggle.rs +++ b/core/src/traits/toggle.rs @@ -2,21 +2,19 @@ Appellation: toggle Contrib: FL03 */ -use core::any::Any; /// Typically, [TypeTag] is used for uninitaliziable `enums` with no variants -pub trait TypeTag: 'static { - fn is(&self) -> bool where T: Any + ?Sized { - crate::type_of::() - } -} +pub trait TypeTag: 'static {} -pub trait BinaryTag: TypeTag { - const MODE: bool; +#[doc(hidden)] +pub trait Context { + type Elem; } /* ************* Implementations ************* */ -impl TypeTag for T where T: 'static {} \ No newline at end of file +impl dyn TypeTag {} + +impl dyn Context {} \ No newline at end of file diff --git a/core/src/types/mod.rs b/core/src/types/mod.rs index 81388f03..d0a33a6b 100644 --- a/core/src/types/mod.rs +++ b/core/src/types/mod.rs @@ -3,45 +3,9 @@ Contrib: FL03 */ pub use self::direction::Direction; -#[cfg(any(feature = "alloc", feature = "std"))] -pub use self::rustic::*; -#[cfg(feature = "std")] -pub use self::std_types::*; pub mod direction; -#[cfg(any(feature = "alloc", feature = "std"))] -mod rustic { - #[cfg(all(feature = "alloc", no_std))] - use alloc::boxed::Box; - #[cfg(feature = "std")] - use std::boxed::Box; - - pub type BoxAny = Box; -} - -#[cfg(feature = "std")] -mod std_types { - use std::sync::{Arc, Mutex}; - - /// Type alias for async errors - pub type AsyncError = Box; - /// Type alias for async results - pub type AsyncResult = core::result::Result; - /// Type alias for a boxed error with send, sync, and static flags enabled - pub type BoxError = Box; - /// Type alias for the standard result used - pub type BoxResult = core::result::Result; - /// Type alias wrapping a locked, thread-safe structure with a [std::sync::Mutex] in an [std::sync::Arc] - pub type Locked = Arc>; - /// Type alias for [std::io::Result] - pub type IOResult = std::io::Result; -} - pub(crate) mod prelude { pub use super::direction::Direction; - #[cfg(any(feature = "alloc", feature = "std"))] - pub use super::rustic::*; - #[cfg(feature = "std")] - pub use super::std_types::*; } diff --git a/core/src/utils.rs b/core/src/utils.rs index 52234562..3de9f5c3 100644 --- a/core/src/utils.rs +++ b/core/src/utils.rs @@ -8,6 +8,9 @@ pub use self::std_utils::*; #[cfg(all(feature = "alloc", no_std))] pub use alloc::string::String; + +pub(crate) mod std_utils; + /// Compare two types pub fn type_of() -> bool where @@ -69,40 +72,3 @@ pub fn snakecase(name: impl ToString) -> String { buffer } - -#[cfg(feature = "std")] -mod std_utils { - pub use self::fs::*; - - /// Fetch the project root unless specified otherwise with a CARGO_MANIFEST_DIR env variable - pub fn project_root() -> std::path::PathBuf { - std::path::Path::new(&env!("CARGO_MANIFEST_DIR")) - .ancestors() - .nth(1) - .unwrap() - .to_path_buf() - } - - mod fs { - use std::fs::File; - use std::io::{self, BufRead, BufReader}; - /// A generic function wrapper extending glob::glob - pub fn collect_files_as(f: &dyn Fn(std::path::PathBuf) -> T, pat: &str) -> Vec { - let mut files = Vec::::new(); - for path in glob::glob(pat).expect("Failed to read glob pattern...") { - if let Ok(r) = path { - files.push(f(r)) - } - continue; - } - files - } - - /// This function converts the file found at path (fp) into a [Vec] - pub fn file_to_vec(fp: String) -> Result, io::Error> { - let file_in = File::open(fp)?; - let file_reader = BufReader::new(file_in); - Ok(file_reader.lines().filter_map(Result::ok).collect()) - } - } -} diff --git a/core/src/utils/std_utils.rs b/core/src/utils/std_utils.rs new file mode 100644 index 00000000..20f3df43 --- /dev/null +++ b/core/src/utils/std_utils.rs @@ -0,0 +1,37 @@ + + +#![cfg(feature = "std")] + +pub use self::fs::*; + + /// Fetch the project root unless specified otherwise with a CARGO_MANIFEST_DIR env variable + pub fn project_root() -> std::path::PathBuf { + std::path::Path::new(&env!("CARGO_MANIFEST_DIR")) + .ancestors() + .nth(1) + .unwrap() + .to_path_buf() + } + + mod fs { + use std::fs::File; + use std::io::{self, BufRead, BufReader}; + /// A generic function wrapper extending glob::glob + pub fn collect_files_as(f: &dyn Fn(std::path::PathBuf) -> T, pat: &str) -> Vec { + let mut files = Vec::::new(); + for path in glob::glob(pat).expect("Failed to read glob pattern...") { + if let Ok(r) = path { + files.push(f(r)) + } + continue; + } + files + } + + /// This function converts the file found at path (fp) into a [Vec] + pub fn file_to_vec(fp: String) -> Result, io::Error> { + let file_in = File::open(fp)?; + let file_reader = BufReader::new(file_in); + Ok(file_reader.lines().filter_map(Result::ok).collect()) + } + } \ No newline at end of file diff --git a/core/tests/errors.rs b/core/tests/errors.rs index 69461fc9..31bc8c43 100644 --- a/core/tests/errors.rs +++ b/core/tests/errors.rs @@ -4,19 +4,19 @@ */ extern crate scsys_core as scsys; -use scsys::errors::{Error, ErrorKind}; +use scsys::errors::{Error, Errors}; #[test] fn test_error() { let msg = "test"; - let err = Error::new(ErrorKind::custom("custom"), msg.to_string()); - assert_eq!(err.kind(), &ErrorKind::custom("custom")); + let err = Error::new(Errors::custom("custom"), msg.to_string()); + assert_eq!(err.kind(), &Errors::custom("custom")); } #[test] #[cfg(feature = "serde")] fn test_error_serde() { - let kind = ErrorKind::custom("custom".to_string()); + let kind = Errors::custom("custom".to_string()); let message = "test"; let err = Error::new(kind, message); From 07cefa628105917ae946c9f153e6af9bd8813109 Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Sat, 13 Jul 2024 08:22:36 -0500 Subject: [PATCH 08/18] update --- actors/src/states/kinds/binary.rs | 154 ++++++++++++++++++++++++++---- actors/src/states/mod.rs | 16 ++-- core/src/errors/kinds.rs | 8 -- core/src/macros.rs | 2 + core/src/macros/get.rs | 80 ++++++++++++++++ core/src/primitives.rs | 2 +- core/src/traits/dtype.rs | 11 +-- core/src/traits/toggle.rs | 2 +- core/src/utils.rs | 3 +- core/src/utils/std_utils.rs | 56 ++++++----- macros/src/ast/get.rs | 5 + macros/src/ast/mod.rs | 1 + macros/src/gets.rs | 11 +++ macros/src/lib.rs | 8 +- 14 files changed, 282 insertions(+), 77 deletions(-) create mode 100644 core/src/macros/get.rs create mode 100644 macros/src/ast/get.rs create mode 100644 macros/src/ast/mod.rs create mode 100644 macros/src/gets.rs diff --git a/actors/src/states/kinds/binary.rs b/actors/src/states/kinds/binary.rs index 190f0b0a..ea183691 100644 --- a/actors/src/states/kinds/binary.rs +++ b/actors/src/states/kinds/binary.rs @@ -1,62 +1,174 @@ /* - Appellation: binary + Appellation: binary Contrib: FL03 */ use crate::states::StateKind; -use strum::{AsRefStr, Display, EnumCount, EnumIs, EnumIter, EnumString, VariantNames}; +use strum::{EnumCount, EnumIs, VariantNames}; +/// An enumerated type representing the possible binary states of a particular value. #[derive( - AsRefStr, Clone, Copy, Debug, - Default, - Display, - EnumCount, - EnumIs, - EnumIter, - EnumString, Eq, Hash, Ord, PartialEq, PartialOrd, + EnumCount, + strum::EnumDiscriminants, + EnumIs, VariantNames, )] #[cfg_attr( feature = "serde", derive(serde::Deserialize, serde::Serialize), - serde(rename_all = "lowercase", untagged) + serde(rename_all = "lowercase"), + strum_discriminants(derive(serde::Deserialize, serde::Serialize)) +)] +#[repr(C)] +#[strum_discriminants( + name(BinaryState), + derive( + Ord, + PartialOrd, + strum::AsRefStr, + strum::Display, + EnumCount, + EnumIs, + strum::EnumIter, + strum::EnumString, + VariantNames + ) )] -#[repr(u8)] #[strum(serialize_all = "lowercase")] -pub enum BinaryState { - Invalid = 0, - #[default] - Valid = 1, +pub enum BinState { + Invalid(Q), + Valid(Q), +} + +impl BinState { + pub fn from_bool(valid: bool, state: Q) -> Self { + if valid { + Self::Valid(state) + } else { + Self::Invalid(state) + } + } + + pub fn invalid(state: Q) -> Self { + Self::Invalid(state) + } + + pub fn valid(state: Q) -> Self { + Self::Valid(state) + } + + pub fn kind(&self) -> &str { + match self { + Self::Invalid(_) => "invalid", + Self::Valid(_) => "valid", + } + } + + pub fn into_inner(self) -> Q { + match self { + Self::Invalid(q) => q, + Self::Valid(q) => q, + } + } + + pub fn invalidate(self) -> Self { + Self::Invalid(self.into_inner()) + } + + pub fn validate(self) -> Self { + Self::Valid(self.into_inner()) + } + + pub fn update(&mut self, state: Q2) -> BinState { + match self { + Self::Invalid(_) => BinState::Invalid(state), + Self::Valid(_) => BinState::Valid(state), + } + } } impl BinaryState { pub fn new(state: u8) -> Self { - match state { + match state % Self::COUNT as u8 { + 0 => Self::Invalid, 1 => Self::Valid, - _ => Self::Invalid, + _ => panic!("Invalid binary state: {}", state), } } - /// a functional variant constructor for [Invalid](BinaryState::Invalid) + pub fn invalid() -> Self { Self::Invalid } - /// a functional variant constructor for [Valid](BinaryState::Valid) + pub fn valid() -> Self { Self::Valid } +} + +impl AsRef for BinState { + fn as_ref(&self) -> &Q { + match self { + Self::Invalid(q) => q, + Self::Valid(q) => q, + } + } +} + +impl AsMut for BinState { + fn as_mut(&mut self) -> &mut Q { + match self { + Self::Invalid(q) => q, + Self::Valid(q) => q, + } + } +} + +impl Default for BinState { + fn default() -> Self { + Self::Invalid(Q::default()) + } +} + +impl Default for BinaryState { + fn default() -> Self { + Self::Invalid + } +} - pub fn update(&mut self, state: Self) { - *self = state; +impl core::ops::Deref for BinState { + type Target = Q; + + fn deref(&self) -> &Self::Target { + self.as_ref() } } +impl core::ops::DerefMut for BinState { + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut() + } +} + +impl core::fmt::Display for BinState +where + Q: core::fmt::Display, +{ + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", *self) + } +} + +/* + ************* Implementations ************* +*/ +impl StateKind for BinState {} impl StateKind for BinaryState {} macro_rules! impl_std_unary { diff --git a/actors/src/states/mod.rs b/actors/src/states/mod.rs index 07177d3c..7b350ffe 100644 --- a/actors/src/states/mod.rs +++ b/actors/src/states/mod.rs @@ -11,12 +11,12 @@ pub(crate) mod state; pub(crate) mod traits; pub mod kinds { - pub use self::binary::BinaryState; + pub use self::binary::{BinState, BinaryState}; pub mod binary; pub(crate) mod prelude { - pub use super::binary::BinaryState; + pub use super::binary::{BinState, BinaryState}; } } @@ -28,16 +28,16 @@ pub(crate) mod prelude { #[cfg(test)] mod tests { - use super::kinds::BinaryState; + use super::*; use strum::IntoEnumIterator; #[test] fn test_states() { - let a = BinaryState::default(); - let mut b = a; - b *= a; - assert_eq!(a, BinaryState::valid()); - assert_eq!(b, BinaryState::valid()); + let data = "sample"; + let a = BinState::valid(data); + let b = BinState::invalid(data); + assert_ne!(a, b); + assert_eq!(a.as_ref(), b.as_ref()); } #[test] diff --git a/core/src/errors/kinds.rs b/core/src/errors/kinds.rs index 6f97f9f0..2795e49a 100644 --- a/core/src/errors/kinds.rs +++ b/core/src/errors/kinds.rs @@ -11,7 +11,6 @@ pub trait ErrorTy { fn name(&self) -> &str; } - #[derive( AsRefStr, Clone, @@ -58,11 +57,6 @@ impl Errors { } } - - - - - macro_rules! err { ($name:ident $($rest:tt)*) => { #[derive( @@ -130,13 +124,11 @@ impl ExternalError { } } - impl Default for ExternalError { fn default() -> Self { Self::Unknown } } - impl_kind_from!(Error, ExternalError); impl_kind_from!(Operation, OperationalError); diff --git a/core/src/macros.rs b/core/src/macros.rs index e9cbc50e..43877109 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -5,6 +5,8 @@ #[macro_use] mod builder; +#[macro_use] +mod get; #[allow(unused_macros)] macro_rules! impl_fmt { diff --git a/core/src/macros/get.rs b/core/src/macros/get.rs new file mode 100644 index 00000000..8e35e085 --- /dev/null +++ b/core/src/macros/get.rs @@ -0,0 +1,80 @@ +/* + Appellation: get + Contrib: FL03 +*/ + +#[macro_export] +macro_rules! getter { + ($($call:ident$(.$field:ident)?<$out:ty>),* $(,)?) => { + $($crate::getter!(@impl $call$(.$field)?<$out>);)* + }; + ($via:ident::<[$($call:ident$(.$field:ident)?<$out:ty>),* $(,)?]>) => { + $($crate::getter!(@impl $via::$call$(.$field)?<$out>);)* + }; + ($($call:ident$(.$field:ident)?),* $(,)? => $out:ty) => { + $($crate::getter!(@impl $call$(.$field)?<$out>);)* + }; + ($via:ident::<[$($call:ident$(.$field:ident)?),* $(,)?]> => $out:ty) => { + $crate::getter!($via::<[$($call$(.$field)?<$out>),*]>); + }; + + (@impl $call:ident<$out:ty>) => { + $crate::getter!(@impl $call.$call<$out>); + }; + (@impl $via:ident::$call:ident<$out:ty>) => { + $crate::getter!(@impl $via::$call.$call<$out>); + }; + (@impl $call:ident.$field:ident<$out:ty>) => { + pub const fn $call(&self) -> &$out { + &self.$field + } + paste::paste! { + pub fn [< $call _mut>](&mut self) -> &mut $out { + &mut self.$field + } + } + }; + (@impl $via:ident::$call:ident.$field:ident<$out:ty>) => { + /// Returns an immutable reference to + pub const fn $call(&self) -> &$out { + &self.$via.$field + } + + paste::paste! { + pub fn [< $call _mut>](&mut self) -> &mut $out { + &mut self.$via.$field + } + } + }; +} + +macro_rules! impl_getters { + (@impl $call:ident<$out:ty>) => { + $crate::getter!(@impl $call.$call<$out>); + }; + (@impl $via:ident::$call:ident<$out:ty>) => { + $crate::getter!(@impl $via::$call.$call<$out>); + }; + (@impl $call:ident.$field:ident<$out:ty>) => { + pub const fn $call(&self) -> &$out { + &self.$field + } + paste::paste! { + pub fn [< $call _mut>](&mut self) -> &mut $out { + &mut self.$field + } + } + }; + (@impl $via:ident::$call:ident.$field:ident<$out:ty>) => { + /// Returns an immutable reference to + pub const fn $call(&self) -> &$out { + &self.$via.$field + } + + paste::paste! { + pub fn [< $call _mut>](&mut self) -> &mut $out { + &mut self.$via.$field + } + } + }; +} diff --git a/core/src/primitives.rs b/core/src/primitives.rs index ae5d1cdb..7ee25db0 100644 --- a/core/src/primitives.rs +++ b/core/src/primitives.rs @@ -49,4 +49,4 @@ pub(crate) mod rs { pub(crate) use std::sync::{self, Arc}; pub(crate) use std::vec::{self, Vec}; } -} \ No newline at end of file +} diff --git a/core/src/traits/dtype.rs b/core/src/traits/dtype.rs index f56ffe29..5789e666 100644 --- a/core/src/traits/dtype.rs +++ b/core/src/traits/dtype.rs @@ -17,7 +17,6 @@ pub trait IsType: 'static { /// [DType] provides additional information regarding the current type pub trait DType: Any { - fn type_id(&self) -> TypeId { Any::type_id(self) } @@ -25,7 +24,6 @@ pub trait DType: Any { fn type_name(&self) -> &'static str { core::any::type_name::() } - } pub trait DTypeExt: DType { @@ -41,7 +39,10 @@ pub trait DTypeExt: DType { Any::type_id(self) } - fn type_name() -> &'static str where T: ?Sized { + fn type_name() -> &'static str + where + T: ?Sized, + { core::any::type_name::() } } @@ -51,6 +52,4 @@ pub trait DTypeExt: DType { */ impl IsType for T {} -impl dyn DType { - -} +impl dyn DType {} diff --git a/core/src/traits/toggle.rs b/core/src/traits/toggle.rs index 5ea36505..9b605f24 100644 --- a/core/src/traits/toggle.rs +++ b/core/src/traits/toggle.rs @@ -17,4 +17,4 @@ pub trait Context { impl dyn TypeTag {} -impl dyn Context {} \ No newline at end of file +impl dyn Context {} diff --git a/core/src/utils.rs b/core/src/utils.rs index 3de9f5c3..963c66b0 100644 --- a/core/src/utils.rs +++ b/core/src/utils.rs @@ -2,12 +2,11 @@ Appellation: utils Contrib: FL03 */ -use core::any::{Any, TypeId}; #[cfg(feature = "std")] pub use self::std_utils::*; #[cfg(all(feature = "alloc", no_std))] pub use alloc::string::String; - +use core::any::{Any, TypeId}; pub(crate) mod std_utils; diff --git a/core/src/utils/std_utils.rs b/core/src/utils/std_utils.rs index 20f3df43..0e0049b5 100644 --- a/core/src/utils/std_utils.rs +++ b/core/src/utils/std_utils.rs @@ -1,37 +1,35 @@ - - #![cfg(feature = "std")] pub use self::fs::*; - /// Fetch the project root unless specified otherwise with a CARGO_MANIFEST_DIR env variable - pub fn project_root() -> std::path::PathBuf { - std::path::Path::new(&env!("CARGO_MANIFEST_DIR")) - .ancestors() - .nth(1) - .unwrap() - .to_path_buf() - } +/// Fetch the project root unless specified otherwise with a CARGO_MANIFEST_DIR env variable +pub fn project_root() -> std::path::PathBuf { + std::path::Path::new(&env!("CARGO_MANIFEST_DIR")) + .ancestors() + .nth(1) + .unwrap() + .to_path_buf() +} - mod fs { - use std::fs::File; - use std::io::{self, BufRead, BufReader}; - /// A generic function wrapper extending glob::glob - pub fn collect_files_as(f: &dyn Fn(std::path::PathBuf) -> T, pat: &str) -> Vec { - let mut files = Vec::::new(); - for path in glob::glob(pat).expect("Failed to read glob pattern...") { - if let Ok(r) = path { - files.push(f(r)) - } - continue; +mod fs { + use std::fs::File; + use std::io::{self, BufRead, BufReader}; + /// A generic function wrapper extending glob::glob + pub fn collect_files_as(f: &dyn Fn(std::path::PathBuf) -> T, pat: &str) -> Vec { + let mut files = Vec::::new(); + for path in glob::glob(pat).expect("Failed to read glob pattern...") { + if let Ok(r) = path { + files.push(f(r)) } - files + continue; } + files + } - /// This function converts the file found at path (fp) into a [Vec] - pub fn file_to_vec(fp: String) -> Result, io::Error> { - let file_in = File::open(fp)?; - let file_reader = BufReader::new(file_in); - Ok(file_reader.lines().filter_map(Result::ok).collect()) - } - } \ No newline at end of file + /// This function converts the file found at path (fp) into a [Vec] + pub fn file_to_vec(fp: String) -> Result, io::Error> { + let file_in = File::open(fp)?; + let file_reader = BufReader::new(file_in); + Ok(file_reader.lines().filter_map(Result::ok).collect()) + } +} diff --git a/macros/src/ast/get.rs b/macros/src/ast/get.rs new file mode 100644 index 00000000..15e362ea --- /dev/null +++ b/macros/src/ast/get.rs @@ -0,0 +1,5 @@ +pub struct GetAst { + pub name: String, + pub field: String, + pub ty: String, +} diff --git a/macros/src/ast/mod.rs b/macros/src/ast/mod.rs new file mode 100644 index 00000000..125ca70d --- /dev/null +++ b/macros/src/ast/mod.rs @@ -0,0 +1 @@ +pub mod get; diff --git a/macros/src/gets.rs b/macros/src/gets.rs new file mode 100644 index 00000000..98ea818e --- /dev/null +++ b/macros/src/gets.rs @@ -0,0 +1,11 @@ +/* + Appellation: gets + Contrib: FL03 +*/ + +use proc_macro2::TokenStream; + +pub fn _gets(input: TokenStream) -> TokenStream { + println!("display: {:?}", input); + input +} diff --git a/macros/src/lib.rs b/macros/src/lib.rs index a71ce375..8ffe671e 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -7,11 +7,17 @@ //! extern crate proc_macro; +#[allow(dead_code)] +pub(crate) mod ast; +#[allow(dead_code)] +pub(crate) mod gets; + use proc_macro::TokenStream; #[doc(hidden)] +/// A procedural macro for generativly creating getter methods; i.e. $field_name() -> &$field_type and $field_name_mut() -> &mut $field_type #[proc_macro] -pub fn display(input: TokenStream) -> TokenStream { +pub fn gets(input: TokenStream) -> TokenStream { println!("display: {:?}", input); input } From ebd81a9998cbcd6caa16df8cb9020353387e5d17 Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Sat, 13 Jul 2024 08:24:13 -0500 Subject: [PATCH 09/18] update --- actors/src/states/traits.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/actors/src/states/traits.rs b/actors/src/states/traits.rs index 9c799304..e870e96d 100644 --- a/actors/src/states/traits.rs +++ b/actors/src/states/traits.rs @@ -10,7 +10,7 @@ pub trait State where Q: StateKind, { - type State: Borrow; + type Kind: Borrow; } pub trait StateData { @@ -39,5 +39,5 @@ where Q: StateKind, S: Borrow, { - type State = S; + type Kind = S; } From d47f0b26ebf465fb6a7c7c251ae06f02e21ac677 Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Wed, 24 Jul 2024 15:47:04 -0500 Subject: [PATCH 10/18] update --- actors/src/states/state.rs | 5 ++--- core/src/hkt/functor.rs | 11 +++++++---- core/src/hkt/mod.rs | 2 +- core/src/macros.rs | 5 +++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/actors/src/states/state.rs b/actors/src/states/state.rs index 05d50476..1a534a08 100644 --- a/actors/src/states/state.rs +++ b/actors/src/states/state.rs @@ -2,7 +2,6 @@ Appellation: state Contrib: FL03 */ -use core::borrow::{Borrow, BorrowMut}; use scsys::id::AtomicId; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] @@ -44,13 +43,13 @@ impl StateBase { } } -impl Borrow for StateBase { +impl core::borrow::Borrow for StateBase { fn borrow(&self) -> &Q { &self.state } } -impl BorrowMut for StateBase { +impl core::borrow::BorrowMut for StateBase { fn borrow_mut(&mut self) -> &mut Q { &mut self.state } diff --git a/core/src/hkt/functor.rs b/core/src/hkt/functor.rs index 721ea691..78a7fde4 100644 --- a/core/src/hkt/functor.rs +++ b/core/src/hkt/functor.rs @@ -2,13 +2,16 @@ Appellation: functor Contrib: FL03 */ -//! # Functor -//! -//! A functor is a type that when mapped over, preserves the structure of the type while applying a function to the values within the type. -//! Functors are useful for modeling the functional effects on values of parameterized data types. + use super::containers::*; use super::HKT; +/// # Functor +/// +/// Formally, a functor describes the morphisms between categories. +/// +/// A functor is a type that when mapped over, preserves the structure of the type while applying a function to the values within the type. +/// Functors are useful for modeling the functional effects on values of parameterized data types. pub trait Functor: HKT { fn fmap(&self, f: F) -> Self::T where diff --git a/core/src/hkt/mod.rs b/core/src/hkt/mod.rs index 30185cbb..7fa3d759 100644 --- a/core/src/hkt/mod.rs +++ b/core/src/hkt/mod.rs @@ -30,7 +30,7 @@ pub trait HKT { macro_rules! hkt { ($($($p:ident)::*),*) => { $( - hkt!(@impl $($p)::*); + $crate::hkt!(@impl $($p)::*); )* }; (@impl $($p:ident)::*) => { diff --git a/core/src/macros.rs b/core/src/macros.rs index 43877109..b59550d8 100644 --- a/core/src/macros.rs +++ b/core/src/macros.rs @@ -2,11 +2,12 @@ Appellation: macros Contrib: FL03 */ +#![allow(unused)] #[macro_use] -mod builder; +pub(crate) mod builder; #[macro_use] -mod get; +pub(crate) mod get; #[allow(unused_macros)] macro_rules! impl_fmt { From 7839a91f6b8c2d61f69b64b890db41cb12d59e1d Mon Sep 17 00:00:00 2001 From: Joe McCain III Date: Sat, 24 Aug 2024 13:19:45 -0500 Subject: [PATCH 11/18] update Signed-off-by: Joe McCain III --- actors/src/macros.rs | 1 + actors/src/states/kinds/binary.rs | 38 +++++++-------- actors/src/states/kinds/mod.rs | 9 ++++ actors/src/states/mod.rs | 35 +++---------- actors/src/states/state.rs | 81 ++++++++++++++++++++++--------- actors/src/states/traits.rs | 43 ---------------- 6 files changed, 92 insertions(+), 115 deletions(-) create mode 100644 actors/src/states/kinds/mod.rs delete mode 100644 actors/src/states/traits.rs diff --git a/actors/src/macros.rs b/actors/src/macros.rs index 7cfffed2..15e97c8b 100644 --- a/actors/src/macros.rs +++ b/actors/src/macros.rs @@ -10,6 +10,7 @@ macro_rules! enum_from_primitive { (@impl $name:ident($($k:literal: $v:ident),*)<$t:ty>) => { impl From<$t> for $name { fn from(d: $t) -> Self { + use strum::EnumCount; match d as usize % Self::COUNT { $( $k => $name::$v, diff --git a/actors/src/states/kinds/binary.rs b/actors/src/states/kinds/binary.rs index ea183691..476478de 100644 --- a/actors/src/states/kinds/binary.rs +++ b/actors/src/states/kinds/binary.rs @@ -2,9 +2,6 @@ Appellation: binary Contrib: FL03 */ -use crate::states::StateKind; -use strum::{EnumCount, EnumIs, VariantNames}; - /// An enumerated type representing the possible binary states of a particular value. #[derive( Clone, @@ -15,10 +12,10 @@ use strum::{EnumCount, EnumIs, VariantNames}; Ord, PartialEq, PartialOrd, - EnumCount, + strum::EnumCount, strum::EnumDiscriminants, - EnumIs, - VariantNames, + strum::EnumIs, + strum::VariantNames, )] #[cfg_attr( feature = "serde", @@ -34,11 +31,11 @@ use strum::{EnumCount, EnumIs, VariantNames}; PartialOrd, strum::AsRefStr, strum::Display, - EnumCount, - EnumIs, + strum::EnumCount, + strum::EnumIs, strum::EnumIter, strum::EnumString, - VariantNames + strum::VariantNames ) )] #[strum(serialize_all = "lowercase")] @@ -95,8 +92,11 @@ impl BinState { } impl BinaryState { - pub fn new(state: u8) -> Self { - match state % Self::COUNT as u8 { + pub const LEN: usize = 2; + + pub fn from_u8(state: u8) -> Self { + + match state % Self::LEN as u8 { 0 => Self::Invalid, 1 => Self::Valid, _ => panic!("Invalid binary state: {}", state), @@ -168,8 +168,6 @@ where /* ************* Implementations ************* */ -impl StateKind for BinState {} -impl StateKind for BinaryState {} macro_rules! impl_std_unary { ($($($p:ident)::*.$call:ident),*) => { @@ -183,7 +181,7 @@ macro_rules! impl_std_unary { type Output = BinaryState; fn $call(self) -> Self::Output { - BinaryState::new($($p)::*::$call(self as u8)) + BinaryState::from_u8($($p)::*::$call(self as u8)) } } } @@ -210,7 +208,7 @@ macro_rules! impl_std_binary { fn $call(self, rhs: BinaryState) -> Self::Output { let res = $($p)::*::$call(self as u8, rhs as u8); - BinaryState::new(res) + BinaryState::from_u8(res) } } @@ -219,7 +217,7 @@ macro_rules! impl_std_binary { fn $call(self, rhs: &'a BinaryState) -> Self::Output { let res = $($p)::*::$call(*self as u8, *rhs as u8); - BinaryState::new(res) + BinaryState::from_u8(res) } } @@ -228,7 +226,7 @@ macro_rules! impl_std_binary { fn $call(self, rhs: BinaryState) -> Self::Output { let res = $($p)::*::$call(*self as u8, rhs as u8); - BinaryState::new(res) + BinaryState::from_u8(res) } } @@ -237,7 +235,7 @@ macro_rules! impl_std_binary { fn $call(self, rhs: &'a BinaryState) -> Self::Output { let res = $($p)::*::$call(self as u8, *rhs as u8); - BinaryState::new(res) + BinaryState::from_u8(res) } } }; @@ -263,7 +261,7 @@ macro_rules! impl_std_binary { fn $call(self, rhs: T) -> Self::Output { let res = $($p)::*::$call(self as u8, rhs); - BinaryState::new(res) + BinaryState::from_u8(res) } } @@ -272,7 +270,7 @@ macro_rules! impl_std_binary { fn $call(self, rhs: T) -> Self::Output { let res = $($p)::*::$call(*self as u8, rhs); - BinaryState::new(res) + BinaryState::from_u8(res) } } }; diff --git a/actors/src/states/kinds/mod.rs b/actors/src/states/kinds/mod.rs new file mode 100644 index 00000000..7cd1b8a8 --- /dev/null +++ b/actors/src/states/kinds/mod.rs @@ -0,0 +1,9 @@ +/* + Appellation: kinds + Contrib: FL03 +*/ +#[doc(inline)] +pub use self::binary::*; + +pub(crate) mod binary; + diff --git a/actors/src/states/mod.rs b/actors/src/states/mod.rs index 7b350ffe..d6e9614e 100644 --- a/actors/src/states/mod.rs +++ b/actors/src/states/mod.rs @@ -5,46 +5,25 @@ //! # States //! //! This modules works to implement a host of primitives and utilities for working with stateful objects. -pub use self::{kinds::prelude::*, state::StateBase, traits::*}; +#[doc(inline)] +pub use self::state::*; pub(crate) mod state; -pub(crate) mod traits; -pub mod kinds { - pub use self::binary::{BinState, BinaryState}; - - pub mod binary; - - pub(crate) mod prelude { - pub use super::binary::{BinState, BinaryState}; - } -} +pub mod kinds; pub(crate) mod prelude { - pub use super::kinds::prelude::*; - pub use super::state::StateBase; - pub use super::traits::*; + pub use super::state::*; } #[cfg(test)] mod tests { use super::*; - use strum::IntoEnumIterator; #[test] - fn test_states() { - let data = "sample"; - let a = BinState::valid(data); - let b = BinState::invalid(data); - assert_ne!(a, b); - assert_eq!(a.as_ref(), b.as_ref()); - } + fn test_state() { + let state = State::binary(true); - #[test] - #[cfg(feature = "std")] - fn test_states_iter() { - let a: Vec = BinaryState::iter().collect(); - assert_eq!(a.len(), 2); - assert_eq!(a[0], BinaryState::invalid()); + assert!(*state.get()); } } diff --git a/actors/src/states/state.rs b/actors/src/states/state.rs index 1a534a08..f2dd6d41 100644 --- a/actors/src/states/state.rs +++ b/actors/src/states/state.rs @@ -2,55 +2,88 @@ Appellation: state Contrib: FL03 */ -use scsys::id::AtomicId; +use core::marker::PhantomData; + +pub trait Stateful { + type Q: ?Sized; +} + +pub trait RawState { + type Data; +} + +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub enum Binary {} + +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub enum Ternary {} + +impl RawState for Binary { + type Data = bool; +} + +impl RawState for Ternary { + type Data = (bool, bool); +} + +pub type BinaryState = State; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[repr(C)] -pub struct StateBase { - id: AtomicId, +pub struct State { data: T, - state: S, + _state: PhantomData, } -impl StateBase { - pub fn new(data: T, state: Q) -> Self { +impl State { + pub fn new(data: T) -> Self { Self { - id: AtomicId::new(), data, - state, + _state: PhantomData::, } } - pub const fn id(&self) -> AtomicId { - self.id - } - - pub fn data(&self) -> &T { + pub const fn get(&self) -> &T { &self.data } - pub fn data_mut(&mut self) -> &mut T { + pub fn get_mut(&mut self) -> &mut T { &mut self.data } - pub fn state(&self) -> &Q { - &self.state + pub fn set(&mut self, data: T) { + self.data = data; } - pub fn state_mut(&mut self) -> &mut Q { - &mut self.state + pub fn cast(self) -> State { + State { + data: self.data, + _state: PhantomData::, + } } } -impl core::borrow::Borrow for StateBase { - fn borrow(&self) -> &Q { - &self.state +impl State { + pub fn binary(data: T) -> Self { + Self { + data, + _state: PhantomData::, + } + } + +} + +impl core::borrow::Borrow for State { + fn borrow(&self) -> &T { + &self.data } } -impl core::borrow::BorrowMut for StateBase { - fn borrow_mut(&mut self) -> &mut Q { - &mut self.state +impl core::borrow::BorrowMut for State { + fn borrow_mut(&mut self) -> &mut T { + &mut self.data } } diff --git a/actors/src/states/traits.rs b/actors/src/states/traits.rs deleted file mode 100644 index e870e96d..00000000 --- a/actors/src/states/traits.rs +++ /dev/null @@ -1,43 +0,0 @@ -/* - Appellation: traits - Contrib: FL03 -*/ -use core::borrow::Borrow; - -pub trait StateKind {} - -pub trait State -where - Q: StateKind, -{ - type Kind: Borrow; -} - -pub trait StateData { - type Item: ?Sized; -} - -/// [Stateful] describes a stateful object -pub trait Stateful -where - Q: StateKind, -{ - type State: State; - - /// [Stateful::state] is used to get the state of the object - fn state(&self) -> &Self::State; - /// [Stateful::update_state] is used to update the state of the object - fn update_state(&mut self, state: Self::State); -} - -/* - ******** implementations ******** -*/ - -impl State for S -where - Q: StateKind, - S: Borrow, -{ - type Kind = S; -} From 76a25751ebe29c7be33a1f2008c1bba985cde2a0 Mon Sep 17 00:00:00 2001 From: FL03 Date: Mon, 9 Sep 2024 07:44:24 -0500 Subject: [PATCH 12/18] update Signed-off-by: FL03 --- .github/ISSUE_TEMPLATE/SCIP.md | 22 -- .github/ISSUE_TEMPLATE/bug_report.md | 24 +- .github/ISSUE_TEMPLATE/feature_request.md | 8 +- .github/ISSUE_TEMPLATE/tracking.md | 4 +- .github/dependabot.yml | 4 +- .github/workflows/clippy.yml | 2 +- .github/workflows/crates.yml | 2 +- .github/workflows/rust.yml | 47 ++-- actors/src/lib.rs | 6 +- actors/src/state/base_state.rs | 35 +++ actors/src/state/kinds.rs | 19 ++ actors/src/state/mod.rs | 54 ++++ actors/src/states/kinds/binary.rs | 292 ---------------------- actors/src/states/kinds/mod.rs | 9 - actors/src/states/mod.rs | 29 --- actors/src/states/state.rs | 89 ------- core/src/hkt/functor.rs | 4 +- 17 files changed, 159 insertions(+), 491 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/SCIP.md create mode 100644 actors/src/state/base_state.rs create mode 100644 actors/src/state/kinds.rs create mode 100644 actors/src/state/mod.rs delete mode 100644 actors/src/states/kinds/binary.rs delete mode 100644 actors/src/states/kinds/mod.rs delete mode 100644 actors/src/states/mod.rs delete mode 100644 actors/src/states/state.rs diff --git a/.github/ISSUE_TEMPLATE/SCIP.md b/.github/ISSUE_TEMPLATE/SCIP.md deleted file mode 100644 index eebafdbc..00000000 --- a/.github/ISSUE_TEMPLATE/SCIP.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -about: A template outlining the structure of a formal proposal for a project improvement. -assignees: - - 'FL03 (https://github.com/FL03)' -name: Project Improvement Proposals -labels: ['scip'] -title: 'SCIP-' ---- - -**Abstract** -A formal summarization of the proposed implementation - -**Concepts** -Outline basic concepts crucial for understanding and / or for validating motivations to explore the proposal - -**Considerations** -A clear and concise description of any alternative solutions or features you've considered. - -**Discussion** -Add any other context or screenshots about the feature request here. - -### Additional Resources \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea78..5423d98d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,10 +1,9 @@ --- -name: Bug report about: Create a report to help us improve +assignees: [ FL03 ] +labels: [ bug ] +name: Bug report title: '' -labels: '' -assignees: '' - --- **Describe the bug** @@ -12,6 +11,7 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: + 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' @@ -24,15 +24,17 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..a1298cd6 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,9 +1,9 @@ --- +about: Create a report to help us improve +assignees: [ FL03 ] +labels: [ enhancement ] name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' +title: 'Feature Request: ' --- diff --git a/.github/ISSUE_TEMPLATE/tracking.md b/.github/ISSUE_TEMPLATE/tracking.md index 32a3eb4b..effce8d2 100644 --- a/.github/ISSUE_TEMPLATE/tracking.md +++ b/.github/ISSUE_TEMPLATE/tracking.md @@ -1,10 +1,10 @@ --- -about: Create a new tracking issue to track the progress of a proposal or feature. +about: A template for creating issues dedicated to tracking other issues and pull requests assignees: [FL03] labels: [ 'tracking' ] projects: [ '@scattered-systems/scsys:features' ] name: Tracking Issue -title: 'Tracking Issue:' +title: 'Tracking Issue: ' --- _Describe the issue(s) or feature being tracked..._ diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0456ea2f..74833381 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,11 +3,11 @@ updates: - package-ecosystem: cargo directory: / schedule: - interval: weekly + interval: monthly - package-ecosystem: github-actions directory: / schedule: - interval: weekly + interval: monthly - package-ecosystem: cargo directory: /actors schedule: diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index f6e706d2..4ced6e06 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -1,8 +1,8 @@ name: Clippy concurrency: - group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.ref }} on: pull_request: diff --git a/.github/workflows/crates.yml b/.github/workflows/crates.yml index babb5dc8..b735cd1f 100644 --- a/.github/workflows/crates.yml +++ b/.github/workflows/crates.yml @@ -1,8 +1,8 @@ name: crates.io concurrency: + cancel-in-progress: true group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: false env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 94810fd0..36f3b445 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,8 +1,8 @@ name: Rust concurrency: + cancel-in-progress: true group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: false env: CARGO_TERM_COLOR: always @@ -17,7 +17,7 @@ on: workflow_dispatch: jobs: - builder: + workspace: name: Build strategy: matrix: @@ -26,22 +26,34 @@ jobs: runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v4 - - name: setup (langspace) - run: rustup default ${{ matrix.toolchain }} && rustup update - - name: Build + - name: rustup + run: | + rustup default ${{ matrix.toolchain }} + rustup update + - name: build run: cargo build --all-features -r -v --workspace - - name: Cache build - id: cache-build + - name: sest + run: cargo test --all-features -r -v --workspace + - name: bench + if: matrix.toolchain == 'nightly' + run: cargo bench --all-features -v --workspace + - name: cache + id: cache uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git + target/debug target/release - key: ${{ matrix.toolchain }}-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - test: + key: ${{ runner.os }}-cargo-${{ matrix.toolchain }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo-${{ matrix.toolchain }}- + ${{ runner.os }}-cargo- + ${{ runner.os }}- + no_std: continue-on-error: true - name: Test (features) + name: test (no_std) strategy: matrix: package: [ core ] @@ -53,17 +65,4 @@ jobs: - run: rustup default ${{ matrix.toolchain }} && rustup update - name: Test (${{ matrix.package }}) run: cargo test ${{ matrix.flags }} -p ${{ matrix.package }} -r -v - workspace: - name: Workspace - strategy: - matrix: - toolchain: [ stable, nightly ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: rustup default ${{ matrix.toolchain }} && rustup update - - name: Test - run: cargo test --all-features -r -v --workspace - - name: Bench - if: matrix.toolchain == 'nightly' - run: cargo bench --all-features -v --workspace + diff --git a/actors/src/lib.rs b/actors/src/lib.rs index d8607992..1b4813a9 100644 --- a/actors/src/lib.rs +++ b/actors/src/lib.rs @@ -12,7 +12,7 @@ extern crate alloc; extern crate scsys_core as scsys; -pub use self::{actor::*, traits::*}; +pub use self::{state::State, traits::*}; pub(crate) mod actor; #[macro_use] @@ -20,7 +20,7 @@ pub(crate) mod macros; pub mod messages; pub mod power; -pub mod states; +pub mod state; pub mod traits; pub type Job = Box; @@ -29,6 +29,6 @@ pub mod prelude { pub use crate::actor::*; pub use crate::messages::*; pub use crate::power::*; - pub use crate::states::prelude::*; + pub use crate::state::prelude::*; pub use crate::traits::prelude::*; } diff --git a/actors/src/state/base_state.rs b/actors/src/state/base_state.rs new file mode 100644 index 00000000..0a3bcdcb --- /dev/null +++ b/actors/src/state/base_state.rs @@ -0,0 +1,35 @@ +/* + Appellation: state + Contrib: FL03 +*/ +use core::marker::PhantomData; + +/// [State] is an abstract object that allows a particular _kind_ of state to be associated +/// with some data. +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub struct State { + pub(crate) data: V, + pub(crate) _state: PhantomData, +} + +impl State { + pub fn new(data: V) -> Self { + Self { + data, + _state: PhantomData::, + } + } + + pub fn data(&self) -> &V { + &self.data + } + + pub fn is_state(&self) -> bool + where + K: 'static, + { + use core::any::TypeId; + TypeId::of::>() == TypeId::of::>() + } +} diff --git a/actors/src/state/kinds.rs b/actors/src/state/kinds.rs new file mode 100644 index 00000000..49d7766c --- /dev/null +++ b/actors/src/state/kinds.rs @@ -0,0 +1,19 @@ +/* + Appellation: binary + Contrib: FL03 +*/ +use super::State; + +pub enum Unary {} + +pub enum Binary {} + +pub enum Ternary {} + +pub enum Nary {} + +pub type BinaryState = State; + +pub type UnaryState = State; + +pub type NState = State, T>; diff --git a/actors/src/state/mod.rs b/actors/src/state/mod.rs new file mode 100644 index 00000000..73393b75 --- /dev/null +++ b/actors/src/state/mod.rs @@ -0,0 +1,54 @@ +/* + Appellation: state + Contrib: FL03 +*/ +//! # State +//! +//! This module contains the stateful types and traits for the library. +#[doc(inline)] +pub use self::{base_state::*, kinds::*}; + +mod base_state; +mod kinds; + +#[allow(unused_imports)] +pub(crate) mod prelude { + pub use super::base_state::*; + pub use super::kinds::*; +} + +/// [Stateful] +pub trait Stateful { + type State: RawState; +} +/// [RawState] +pub trait RawState { + type Inner; + type Tag; +} + +/* + ************* Implementations ************* +*/ +impl RawState for State { + type Inner = T; + type Tag = Q; +} + +impl Stateful for State { + type State = State; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_nary_state() { + let state = NState::::new(0); + assert!(state.is_state::>()); + + assert!(!state.is_state::>()); + assert!(!state.is_state::>()); + } +} diff --git a/actors/src/states/kinds/binary.rs b/actors/src/states/kinds/binary.rs deleted file mode 100644 index 476478de..00000000 --- a/actors/src/states/kinds/binary.rs +++ /dev/null @@ -1,292 +0,0 @@ -/* - Appellation: binary - Contrib: FL03 -*/ -/// An enumerated type representing the possible binary states of a particular value. -#[derive( - Clone, - Copy, - Debug, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - strum::EnumCount, - strum::EnumDiscriminants, - strum::EnumIs, - strum::VariantNames, -)] -#[cfg_attr( - feature = "serde", - derive(serde::Deserialize, serde::Serialize), - serde(rename_all = "lowercase"), - strum_discriminants(derive(serde::Deserialize, serde::Serialize)) -)] -#[repr(C)] -#[strum_discriminants( - name(BinaryState), - derive( - Ord, - PartialOrd, - strum::AsRefStr, - strum::Display, - strum::EnumCount, - strum::EnumIs, - strum::EnumIter, - strum::EnumString, - strum::VariantNames - ) -)] -#[strum(serialize_all = "lowercase")] -pub enum BinState { - Invalid(Q), - Valid(Q), -} - -impl BinState { - pub fn from_bool(valid: bool, state: Q) -> Self { - if valid { - Self::Valid(state) - } else { - Self::Invalid(state) - } - } - - pub fn invalid(state: Q) -> Self { - Self::Invalid(state) - } - - pub fn valid(state: Q) -> Self { - Self::Valid(state) - } - - pub fn kind(&self) -> &str { - match self { - Self::Invalid(_) => "invalid", - Self::Valid(_) => "valid", - } - } - - pub fn into_inner(self) -> Q { - match self { - Self::Invalid(q) => q, - Self::Valid(q) => q, - } - } - - pub fn invalidate(self) -> Self { - Self::Invalid(self.into_inner()) - } - - pub fn validate(self) -> Self { - Self::Valid(self.into_inner()) - } - - pub fn update(&mut self, state: Q2) -> BinState { - match self { - Self::Invalid(_) => BinState::Invalid(state), - Self::Valid(_) => BinState::Valid(state), - } - } -} - -impl BinaryState { - pub const LEN: usize = 2; - - pub fn from_u8(state: u8) -> Self { - - match state % Self::LEN as u8 { - 0 => Self::Invalid, - 1 => Self::Valid, - _ => panic!("Invalid binary state: {}", state), - } - } - - pub fn invalid() -> Self { - Self::Invalid - } - - pub fn valid() -> Self { - Self::Valid - } -} - -impl AsRef for BinState { - fn as_ref(&self) -> &Q { - match self { - Self::Invalid(q) => q, - Self::Valid(q) => q, - } - } -} - -impl AsMut for BinState { - fn as_mut(&mut self) -> &mut Q { - match self { - Self::Invalid(q) => q, - Self::Valid(q) => q, - } - } -} - -impl Default for BinState { - fn default() -> Self { - Self::Invalid(Q::default()) - } -} - -impl Default for BinaryState { - fn default() -> Self { - Self::Invalid - } -} - -impl core::ops::Deref for BinState { - type Target = Q; - - fn deref(&self) -> &Self::Target { - self.as_ref() - } -} - -impl core::ops::DerefMut for BinState { - fn deref_mut(&mut self) -> &mut Self::Target { - self.as_mut() - } -} - -impl core::fmt::Display for BinState -where - Q: core::fmt::Display, -{ - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, "{}", *self) - } -} - -/* - ************* Implementations ************* -*/ - -macro_rules! impl_std_unary { - ($($($p:ident)::*.$call:ident),*) => { - $(impl_std_unary!(@impl $($p)::*.$call);)* - }; - (std $($trait:ident.$call:ident),*) => { - $(impl_std_unary!(@impl core::ops::$trait.$call);)* - }; - (@impl $($p:ident)::*.$call:ident) => { - impl $($p)::* for BinaryState { - type Output = BinaryState; - - fn $call(self) -> Self::Output { - BinaryState::from_u8($($p)::*::$call(self as u8)) - } - } - } -} - -macro_rules! impl_std_binary { - ($($($p:ident)::*.$call:ident),*) => { - $(impl_std_binary!(@impl $($p)::*.$call);)* - }; - (std $($trait:ident.$call:ident),*) => { - $( - impl_std_binary!(@assign $trait.$call); - impl_std_binary!(@impl core::ops::$trait.$call); - )* - }; - (@impl $($p:ident)::*.$call:ident) => { - impl_std_binary!(@self $($p)::*.$call); - impl_std_binary!(@primitive $($p)::*.$call); - }; - - (@self $($p:ident)::*.$call:ident) => { - impl $($p)::* for BinaryState { - type Output = BinaryState; - - fn $call(self, rhs: BinaryState) -> Self::Output { - let res = $($p)::*::$call(self as u8, rhs as u8); - BinaryState::from_u8(res) - } - } - - impl<'a> $($p)::* for &'a BinaryState { - type Output = BinaryState; - - fn $call(self, rhs: &'a BinaryState) -> Self::Output { - let res = $($p)::*::$call(*self as u8, *rhs as u8); - BinaryState::from_u8(res) - } - } - - impl<'a> $($p)::* for &'a BinaryState { - type Output = BinaryState; - - fn $call(self, rhs: BinaryState) -> Self::Output { - let res = $($p)::*::$call(*self as u8, rhs as u8); - BinaryState::from_u8(res) - } - } - - impl<'a> $($p)::*<&'a BinaryState> for BinaryState { - type Output = BinaryState; - - fn $call(self, rhs: &'a BinaryState) -> Self::Output { - let res = $($p)::*::$call(self as u8, *rhs as u8); - BinaryState::from_u8(res) - } - } - }; - (@assign $trait:ident.$call:ident) => { - paste::paste! { - impl core::ops::[<$trait Assign>] for BinaryState { - fn [<$call _assign>](&mut self, rhs: BinaryState) { - *self = core::ops::$trait::$call(*self, rhs); - } - } - - impl<'a> core::ops::[<$trait Assign>]<&'a BinaryState> for BinaryState { - fn [<$call _assign>](&mut self, rhs: &'a BinaryState) { - *self = core::ops::$trait::$call(*self, rhs); - } - } - } - }; - - (@primitive $($p:ident)::*.$call:ident) => { - impl $($p)::* for BinaryState where u8: $($p)::* { - type Output = BinaryState; - - fn $call(self, rhs: T) -> Self::Output { - let res = $($p)::*::$call(self as u8, rhs); - BinaryState::from_u8(res) - } - } - - impl<'a, T> $($p)::* for &'a BinaryState where u8: $($p)::* { - type Output = BinaryState; - - fn $call(self, rhs: T) -> Self::Output { - let res = $($p)::*::$call(*self as u8, rhs); - BinaryState::from_u8(res) - } - } - }; - -} - -macro_rules! impl_from { - ($($t:ty),*) => { - $( - enum_from_primitive!(BinaryState(0: Invalid, 1: Valid)<$t>); - )* - }; -} - -impl_std_binary!(std Add.add, Div.div, Mul.mul, Rem.rem, Sub.sub); -impl_std_binary!(std BitAnd.bitand, BitOr.bitor, BitXor.bitxor, Shl.shl, Shr.shr); -impl_std_unary!(core::ops::Not.not); - -impl_from!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize); diff --git a/actors/src/states/kinds/mod.rs b/actors/src/states/kinds/mod.rs deleted file mode 100644 index 7cd1b8a8..00000000 --- a/actors/src/states/kinds/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -/* - Appellation: kinds - Contrib: FL03 -*/ -#[doc(inline)] -pub use self::binary::*; - -pub(crate) mod binary; - diff --git a/actors/src/states/mod.rs b/actors/src/states/mod.rs deleted file mode 100644 index d6e9614e..00000000 --- a/actors/src/states/mod.rs +++ /dev/null @@ -1,29 +0,0 @@ -/* - Appellation: states - Contrib: FL03 -*/ -//! # States -//! -//! This modules works to implement a host of primitives and utilities for working with stateful objects. -#[doc(inline)] -pub use self::state::*; - -pub(crate) mod state; - -pub mod kinds; - -pub(crate) mod prelude { - pub use super::state::*; -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_state() { - let state = State::binary(true); - - assert!(*state.get()); - } -} diff --git a/actors/src/states/state.rs b/actors/src/states/state.rs deleted file mode 100644 index f2dd6d41..00000000 --- a/actors/src/states/state.rs +++ /dev/null @@ -1,89 +0,0 @@ -/* - Appellation: state - Contrib: FL03 -*/ -use core::marker::PhantomData; - -pub trait Stateful { - type Q: ?Sized; -} - -pub trait RawState { - type Data; -} - -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub enum Binary {} - -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub enum Ternary {} - -impl RawState for Binary { - type Data = bool; -} - -impl RawState for Ternary { - type Data = (bool, bool); -} - -pub type BinaryState = State; - -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -#[repr(C)] -pub struct State { - data: T, - _state: PhantomData, -} - -impl State { - pub fn new(data: T) -> Self { - Self { - data, - _state: PhantomData::, - } - } - - pub const fn get(&self) -> &T { - &self.data - } - - pub fn get_mut(&mut self) -> &mut T { - &mut self.data - } - - pub fn set(&mut self, data: T) { - self.data = data; - } - - pub fn cast(self) -> State { - State { - data: self.data, - _state: PhantomData::, - } - } -} - -impl State { - pub fn binary(data: T) -> Self { - Self { - data, - _state: PhantomData::, - } - } - -} - -impl core::borrow::Borrow for State { - fn borrow(&self) -> &T { - &self.data - } -} - -impl core::borrow::BorrowMut for State { - fn borrow_mut(&mut self) -> &mut T { - &mut self.data - } -} diff --git a/core/src/hkt/functor.rs b/core/src/hkt/functor.rs index 78a7fde4..3e32d20c 100644 --- a/core/src/hkt/functor.rs +++ b/core/src/hkt/functor.rs @@ -8,8 +8,8 @@ use super::HKT; /// # Functor /// -/// Formally, a functor describes the morphisms between categories. -/// +/// Formally, a functor describes the morphisms between categories. +/// /// A functor is a type that when mapped over, preserves the structure of the type while applying a function to the values within the type. /// Functors are useful for modeling the functional effects on values of parameterized data types. pub trait Functor: HKT { From 16a7443aa026a935fe931309654936feadfc0b94 Mon Sep 17 00:00:00 2001 From: FL03 Date: Sun, 22 Sep 2024 11:23:41 -0500 Subject: [PATCH 13/18] update Signed-off-by: FL03 --- .github/workflows/clippy.yml | 2 +- .github/workflows/crates.yml | 5 +- .github/workflows/rust.yml | 42 ++++-- Cargo.toml | 3 +- actors/src/messages/message.rs | 2 +- core/Cargo.toml | 9 ++ core/src/errors/error.rs | 34 ++--- core/src/errors/kinds.rs | 5 +- core/src/errors/mod.rs | 4 +- core/src/hkt/applicative.rs | 5 +- core/src/hkt/functor.rs | 4 +- core/src/hkt/mod.rs | 44 +++--- core/src/hkt/monad.rs | 48 +++--- core/src/id/mod.rs | 4 + core/src/id/traits.rs | 8 +- core/src/lib.rs | 25 ++-- core/src/name/mod.rs | 2 +- core/src/primitives.rs | 52 ------- core/src/stores/kv.rs | 13 +- core/src/time/datetime.rs | 15 +- core/src/time/epoch.rs | 21 ++- core/src/time/mod.rs | 67 +++++++-- core/src/time/timestamp.rs | 186 ++++++++++++++++-------- core/src/traits/appellation.rs | 18 +-- core/src/traits/classify.rs | 6 +- core/src/traits/dtype.rs | 2 +- core/src/traits/ext/string.rs | 4 +- core/src/traits/mod.rs | 43 +++--- core/src/types/mod.rs | 50 +++++++ core/src/utils.rs | 71 ++------- core/src/utils/alloc.rs | 58 ++++++++ core/src/utils/{std_utils.rs => std.rs} | 4 + 32 files changed, 490 insertions(+), 366 deletions(-) delete mode 100644 core/src/primitives.rs create mode 100644 core/src/utils/alloc.rs rename core/src/utils/{std_utils.rs => std.rs} (93%) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 4ced6e06..151a6ddb 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -1,7 +1,7 @@ name: Clippy concurrency: - cancel-in-progress: true + cancel-in-progress: false group: ${{ github.workflow }}-${{ github.ref }} on: diff --git a/.github/workflows/crates.yml b/.github/workflows/crates.yml index b735cd1f..3bbf4282 100644 --- a/.github/workflows/crates.yml +++ b/.github/workflows/crates.yml @@ -16,14 +16,12 @@ on: jobs: core: - name: Publish (core) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: publish run: cargo publish --all-features -v -p ${{ github.event.repository.name }}-core --token ${{ secrets.CARGO_REGISTRY_TOKEN }} features: - name: Publish (features) needs: core runs-on: ubuntu-latest strategy: @@ -33,10 +31,9 @@ jobs: PACKAGE_NAME: ${{ github.event.repository.name }}-${{ matrix.package }} steps: - uses: actions/checkout@v4 - - name: Publish (${{ env.PACKAGE_NAME }}) + - name: publish (${{ env.PACKAGE_NAME }}) run: cargo publish --all-features -v -p ${{ env.PACKAGE_NAME }} --token ${{ secrets.CARGO_REGISTRY_TOKEN }} sdk: - name: Publish (sdk) needs: features runs-on: ubuntu-latest steps: diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 36f3b445..1708b3b7 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -18,27 +18,34 @@ on: jobs: workspace: - name: Build strategy: matrix: - platform: [ macos-latest, ubuntu-latest, windows-latest ] + platform: [ ubuntu-latest ] # [ macos-latest, ubuntu-latest, windows-latest ] + target: [ x86_64-unknown-linux-gnu ] toolchain: [ stable, nightly ] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v4 - - name: rustup + - + name: checkout + uses: actions/checkout@v4 + - + name: rustup run: | rustup default ${{ matrix.toolchain }} rustup update - - name: build - run: cargo build --all-features -r -v --workspace - - name: sest - run: cargo test --all-features -r -v --workspace - - name: bench + - + name: build + run: cargo build --all-features -r -v --workspace --target ${{ matrix.target }} + - + name: test + run: cargo test --all-features -r -v --workspace --target ${{ matrix.target }} + - + name: bench if: matrix.toolchain == 'nightly' run: cargo bench --all-features -v --workspace - - name: cache - id: cache + - + id: rust-cache + name: cache uses: actions/cache@v4 with: path: | @@ -53,16 +60,19 @@ jobs: ${{ runner.os }}- no_std: continue-on-error: true - name: test (no_std) + name: Build (no_std) strategy: matrix: package: [ core ] - flags: [ --no-default-features, --all-features ] + flags: [ --no-default-features ] toolchain: [ stable, nightly ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: rustup default ${{ matrix.toolchain }} && rustup update - - name: Test (${{ matrix.package }}) - run: cargo test ${{ matrix.flags }} -p ${{ matrix.package }} -r -v + - + name: rustup + run: rustup default ${{ matrix.toolchain }} && rustup update + - + name: Test (${{ matrix.package }}) + run: cargo test --no-default-features -p ${{ matrix.package }} -r -v diff --git a/Cargo.toml b/Cargo.toml index bd3e8936..b21adf50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,6 @@ members = [ resolver = "2" [workspace.dependencies] -anyhow = "1" lazy_static = "1" num = { default-features = false, version = "0.4" } paste = "1" @@ -41,7 +40,7 @@ debug = true debug-assertions = true incremental = true lto = false -panic = "abort" +panic = "unwind" rpath = false opt-level = 0 overflow-checks = true diff --git a/actors/src/messages/message.rs b/actors/src/messages/message.rs index dd810b69..6177872d 100644 --- a/actors/src/messages/message.rs +++ b/actors/src/messages/message.rs @@ -9,7 +9,7 @@ use scsys::prelude::{AtomicId, Timestamp}; pub struct Message { id: AtomicId, data: Option, - ts: Timestamp, + ts: Timestamp, } impl Message { diff --git a/core/Cargo.toml b/core/Cargo.toml index 261fd506..d6e22191 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -31,6 +31,10 @@ alloc = [ "serde?/alloc", ] +chrono = [ + "dep:chrono" +] + rand = [ "dep:rand", "num/rand", @@ -48,6 +52,7 @@ serde-ext = [ # ******* [FF] Environment ******* std = [ + "alloc", "num/std", "rand?/std", "rand?/std_rng", @@ -83,6 +88,10 @@ num.workspace = true smart-default.workspace = true strum.workspace = true +[dependencies.chrono] +optional = true +version = "0.4" + [dependencies.rand] default-features = false optional = true diff --git a/core/src/errors/error.rs b/core/src/errors/error.rs index 852e6b3c..ac9d75b7 100644 --- a/core/src/errors/error.rs +++ b/core/src/errors/error.rs @@ -4,8 +4,8 @@ */ use super::kinds::*; use crate::id::AtomicId; -#[cfg(all(feature = "alloc", no_std))] -use alloc::string::String; +#[cfg(feature = "alloc")] +use alloc::string::{String, ToString}; #[derive(Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] @@ -13,7 +13,6 @@ pub struct Error { id: AtomicId, kind: Errors, message: String, - ts: u128, } impl Error { @@ -22,7 +21,6 @@ impl Error { id: AtomicId::new(), kind: kind.into(), message: message.to_string(), - ts: crate::time::systime(), } } @@ -42,18 +40,12 @@ impl Error { &self.message } - pub fn timestamp(&self) -> u128 { - self.ts - } - pub fn set_kind(&mut self, kind: Errors) { self.kind = kind; - self.on_update(); } pub fn set_message(&mut self, message: String) { self.message = message; - self.on_update(); } pub fn with_kind(mut self, kind: Errors) -> Self { @@ -65,10 +57,6 @@ impl Error { self.message = message; self } - - fn on_update(&mut self) { - self.ts = crate::time::systime(); - } } unsafe impl Send for Error {} @@ -79,10 +67,9 @@ impl core::fmt::Debug for Error { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!( f, - "*** Error ***\nKind: {}\nTimestamp: {}\nMessage:\n{}\n*** ***", - self.kind(), - self.timestamp(), - self.message() + "[{kind}]: {msg}", + kind = self.kind(), + msg = self.message() ) } } @@ -91,17 +78,16 @@ impl core::fmt::Display for Error { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!( f, - "Error ({}) at {}\n{}", - self.kind(), - self.timestamp(), - self.message() + "[{kind}]: {msg}", + kind = self.kind(), + msg = self.message() ) } } -#[cfg(feature = "std")] -impl std::error::Error for Error {} +impl core::error::Error for Error {} +#[cfg(feature = "alloc")] impl From> for Error { fn from(kind: Errors) -> Self { Self::new(kind, String::new()) diff --git a/core/src/errors/kinds.rs b/core/src/errors/kinds.rs index 2795e49a..21aba480 100644 --- a/core/src/errors/kinds.rs +++ b/core/src/errors/kinds.rs @@ -2,7 +2,7 @@ Appellation: kinds Contrib: FL03 */ -#[cfg(all(feature = "alloc", no_std))] +#[cfg(feature = "alloc")] use alloc::string::String; use smart_default::SmartDefault; use strum::{AsRefStr, Display, EnumCount, EnumIs, VariantNames}; @@ -58,7 +58,7 @@ impl Errors { } macro_rules! err { - ($name:ident $($rest:tt)*) => { + ($(#[$meta:meta])* $name:ident $($rest:tt)*) => { #[derive( Clone, Copy, @@ -81,6 +81,7 @@ macro_rules! err { )] #[non_exhaustive] #[strum(serialize_all = "lowercase")] + $(#[$meta])* pub enum $name $($rest)* }; } diff --git a/core/src/errors/mod.rs b/core/src/errors/mod.rs index 853e78ce..8b3a84ce 100644 --- a/core/src/errors/mod.rs +++ b/core/src/errors/mod.rs @@ -5,13 +5,15 @@ //! # Errors //! //! +#![cfg(feature = "alloc")] +#[doc(inline)] pub use self::{error::*, kinds::*}; pub(crate) mod error; pub(crate) mod kinds; /// A type alias for [core::result::Result] that employs the [crate::errors::Error] type -pub type Result = core::result::Result; +pub type Result = core::result::Result; pub(crate) mod prelude { pub use super::error::Error; diff --git a/core/src/hkt/applicative.rs b/core/src/hkt/applicative.rs index 7fe265c3..bd443d47 100644 --- a/core/src/hkt/applicative.rs +++ b/core/src/hkt/applicative.rs @@ -20,6 +20,7 @@ pub trait Applicative: Functor { Self: HKT; } +#[allow(unused_macros)] macro_rules! applicative { ($($t:ident),* $(,)?) => { $( @@ -42,7 +43,8 @@ macro_rules! applicative { } }; } -#[cfg(any(feature = "std", all(feature = "alloc", no_std)))] + +#[cfg(feature = "alloc")] applicative!(Arc, Box, Rc); impl Applicative for Option { @@ -64,6 +66,7 @@ impl Applicative for Option { } } +#[cfg(feature = "alloc")] impl Applicative for Vec { fn pure_(value: U) -> Self::T { vec![value] diff --git a/core/src/hkt/functor.rs b/core/src/hkt/functor.rs index 3e32d20c..2f9717cd 100644 --- a/core/src/hkt/functor.rs +++ b/core/src/hkt/functor.rs @@ -18,6 +18,7 @@ pub trait Functor: HKT { F: Fn(&Self::C) -> U; } +#[allow(unused_macros)] macro_rules! functor { ($($t:ident),* $(,)?) => { $( @@ -36,7 +37,7 @@ macro_rules! functor { }; } -#[cfg(any(feature = "std", all(feature = "alloc", no_std)))] +#[cfg(feature = "alloc")] functor!(Arc, Box, Rc); impl Functor for Option { @@ -51,6 +52,7 @@ impl Functor for Option { } } +#[cfg(feature = "alloc")] impl Functor for Vec { fn fmap(&self, f: F) -> Vec where diff --git a/core/src/hkt/mod.rs b/core/src/hkt/mod.rs index 7fa3d759..3310e5d0 100644 --- a/core/src/hkt/mod.rs +++ b/core/src/hkt/mod.rs @@ -5,20 +5,25 @@ //! # Higher Kinded Types //! //! -pub use self::prelude::*; +#[doc(inline)] +pub use self::{applicative::*, functor::*, monad::*}; -pub mod applicative; -pub mod functor; -pub mod monad; +mod applicative; +mod functor; +mod monad; + +pub(crate) mod prelude { + pub use super::applicative::Applicative; + pub use super::functor::Functor; + pub use super::monad::Monad; + pub use super::HKT; +} pub(crate) mod containers { pub(crate) use core::option::Option; - #[cfg(all(feature = "alloc", no_std))] + #[cfg(feature = "alloc")] pub(crate) use alloc::{boxed::Box, rc::Rc, sync::Arc, vec::Vec}; - - #[cfg(feature = "std")] - pub(crate) use std::{boxed::Box, rc::Rc, sync::Arc, vec::Vec}; } pub trait HKT { @@ -28,7 +33,7 @@ pub trait HKT { #[macro_export] macro_rules! hkt { - ($($($p:ident)::*),*) => { + ($($($p:ident)::*),* $(,)?) => { $( $crate::hkt!(@impl $($p)::*); )* @@ -41,35 +46,30 @@ macro_rules! hkt { }; } +hkt!(containers::Option); + +#[cfg(feature = "alloc")] hkt!( containers::Arc, containers::Box, - containers::Option, containers::Rc, containers::Vec ); -pub(crate) mod prelude { - pub use super::applicative::Applicative; - pub use super::functor::Functor; - pub use super::monad::Monad; - pub use super::HKT; -} - +#[allow(unused_imports)] #[cfg(test)] mod tests { + use super::*; - use super::functor::Functor; - use super::monad::Monad; - + #[cfg(feature = "alloc")] #[test] fn test_hkt_vec() { let v = Vec::from_iter(0..9); let v2 = v.fmap(|x| (x + 1).to_string()); - assert_eq!(v2, vec!["1", "2", "3", "4", "5", "6", "7", "8", "9"]); + assert_eq!(v2, ["1", "2", "3", "4", "5", "6", "7", "8", "9"]); let v = Vec::return_(0); let v2 = v.bind(|x| vec![x + 1]); - assert_eq!(v2, vec![1]); + assert_eq!(v2, [1]); } } diff --git a/core/src/hkt/monad.rs b/core/src/hkt/monad.rs index 95fe7523..66726c1d 100644 --- a/core/src/hkt/monad.rs +++ b/core/src/hkt/monad.rs @@ -28,45 +28,41 @@ pub trait Monad: Applicative { } } -impl Monad for Arc { - fn bind(&self, mut fs: F) -> Arc - where - F: FnMut(&T) -> Arc, - { - fs(self) - } +#[allow(unused_macros)] +macro_rules! monad { + ($($t:ident),* $(,)?) => { + $( + monad!(@impl $t); + )* + }; + (@impl $t:ident) => { + impl Monad for $t { + fn bind(&self, mut fs: F) -> $t + where + F: FnMut(&T) -> $t, + { + fs(self) + } + } + }; } -impl Monad for Box { - fn bind(&self, mut fs: F) -> Box - where - F: FnMut(&T) -> Box, - { - fs(self) - } -} +#[cfg(feature = "alloc")] +monad!(Arc, Box, Rc); impl Monad for Option { fn bind(&self, mut fs: F) -> Option where F: FnMut(&T) -> Option, { - match *self { - Some(ref value) => fs(value), + match self { + Some(x) => fs(x), None => None, } } } -impl Monad for Rc { - fn bind(&self, mut fs: F) -> Rc - where - F: FnMut(&T) -> Rc, - { - fs(self) - } -} - +#[cfg(feature = "alloc")] impl Monad for Vec { fn bind(&self, mut fs: F) -> Vec where diff --git a/core/src/id/mod.rs b/core/src/id/mod.rs index b9d8adda..bee06da1 100644 --- a/core/src/id/mod.rs +++ b/core/src/id/mod.rs @@ -2,6 +2,10 @@ Appellation: ids Contrib: FL03 */ +//! # Identity +//! +//! The identity module provides a set of traits and types for generating unique identifiers. +#[doc(inline)] pub use self::{kinds::*, traits::*}; pub(crate) mod traits; diff --git a/core/src/id/traits.rs b/core/src/id/traits.rs index 9e3ae1c1..42edaa22 100644 --- a/core/src/id/traits.rs +++ b/core/src/id/traits.rs @@ -2,7 +2,7 @@ Appellation: traits Contrib: FL03 */ -#[cfg(all(feature = "alloc", no_std))] +#[cfg(feature = "alloc")] use alloc::string::{String, ToString}; use core::borrow::Borrow; @@ -23,7 +23,7 @@ where fn get(&self) -> &Self::Item; } -#[cfg(any(all(feature = "alloc", no_std), feature = "std"))] +#[cfg(feature = "alloc")] pub trait IdentifierExt: Identifier where Self: Copy + Eq + Ord + ToString + core::hash::Hash, @@ -74,7 +74,7 @@ where impl HashId for Id where Id: Eq + Identifier + core::hash::Hash {} -#[cfg(any(all(feature = "alloc", no_std), feature = "std"))] +#[cfg(feature = "alloc")] impl IdentifierExt for Id where Id: Copy + Eq + Identifier + Ord + ToString + core::hash::Hash {} macro_rules! identifier { @@ -93,5 +93,5 @@ macro_rules! identifier { identifier!(f32, f64, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize); identifier!(bool, char, &str); -#[cfg(any(feature = "alloc", feature = "std"))] +#[cfg(feature = "alloc")] identifier!(String); diff --git a/core/src/lib.rs b/core/src/lib.rs index 7566f6ba..0ca5ccb4 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -10,45 +10,42 @@ #[cfg(feature = "alloc")] extern crate alloc; -pub use self::{traits::prelude::*, types::prelude::*}; +pub use self::{traits::prelude::*, types::prelude::*, utils::*}; -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(feature = "alloc")] pub use self::errors::{Error, Errors, Result}; -#[cfg(any(feature = "std", feature = "alloc"))] -pub use self::{primitives::*, utils::*}; #[macro_use] pub(crate) mod macros; #[macro_use] -pub(crate) mod primitives; -#[macro_use] pub(crate) mod seal; -#[cfg(any(feature = "std", feature = "alloc"))] pub(crate) mod utils; -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(feature = "alloc")] pub mod errors; -#[cfg(any(feature = "std", feature = "alloc"))] pub mod hkt; pub mod id; #[doc(hidden)] pub mod name; +#[doc(hidden)] pub mod stores; pub mod sync; -#[cfg(feature = "std")] pub mod time; pub mod traits; pub mod types; pub mod prelude { + pub use super::hkt::prelude::*; + #[cfg(feature = "alloc")] + pub use crate::errors::prelude::*; pub use crate::id::prelude::*; + #[doc(hidden)] pub use crate::name::prelude::*; + #[doc(hidden)] pub use crate::stores::prelude::*; pub use crate::sync::prelude::*; - #[cfg(feature = "std")] - pub use crate::time::*; + pub use crate::time::prelude::*; pub use crate::traits::prelude::*; pub use crate::types::prelude::*; - #[cfg(any(feature = "std", feature = "alloc"))] - pub use crate::{errors::prelude::*, hkt::prelude::*, utils::*}; + pub use crate::utils::*; } diff --git a/core/src/name/mod.rs b/core/src/name/mod.rs index baae719e..ad97ba85 100644 --- a/core/src/name/mod.rs +++ b/core/src/name/mod.rs @@ -5,7 +5,7 @@ //! # Name //! //! This module works to implement various naming conventions and name-related primitives. - +#[doc(inline)] pub use self::casing::*; pub(crate) mod casing; diff --git a/core/src/primitives.rs b/core/src/primitives.rs deleted file mode 100644 index 7ee25db0..00000000 --- a/core/src/primitives.rs +++ /dev/null @@ -1,52 +0,0 @@ -/* - Appellation: primitives - Contrib: FL03 -*/ - -#[cfg(feature = "std")] -pub use self::std_types::*; - -#[cfg(feature = "std")] -mod std_types { - use std::sync::{Arc, Mutex}; - /// Type alias for async errors - pub type AsyncError = Box; - /// Type alias for async results - pub type AsyncResult = core::result::Result; - /// Type alias for a boxed error with send, sync, and static flags enabled - pub type BoxError = Box; - /// Type alias for the standard result used - pub type BoxResult = core::result::Result; - /// Type alias wrapping a locked, thread-safe structure with a [Mutex] in an [Arc] - pub type Locked = Arc>; - /// Type alias for [std::io::Result] - pub type IOResult = std::io::Result; -} - -#[allow(unused_imports)] -pub(crate) mod rs { - pub(crate) use core::*; - - #[cfg(all(feature = "alloc", no_std))] - pub(crate) use self::no_std::*; - #[cfg(feature = "std")] - pub(crate) use self::std_ty::*; - - #[cfg(feature = "alloc")] - pub(crate) mod no_std { - pub(crate) use alloc::boxed::{self, Box}; - pub(crate) use alloc::collections::{self, BTreeMap, BTreeSet}; - pub(crate) use alloc::string::{self, String, ToString}; - pub(crate) use alloc::sync::{self, Arc}; - pub(crate) use alloc::vec::{self, Vec}; - } - - #[cfg(feature = "std")] - pub(crate) mod std_ty { - pub(crate) use std::boxed::{self, Box}; - pub(crate) use std::collections::{self, BTreeMap, BTreeSet}; - pub(crate) use std::string::{self, String, ToString}; - pub(crate) use std::sync::{self, Arc}; - pub(crate) use std::vec::{self, Vec}; - } -} diff --git a/core/src/stores/kv.rs b/core/src/stores/kv.rs index 85c00208..d0bf91d1 100644 --- a/core/src/stores/kv.rs +++ b/core/src/stores/kv.rs @@ -2,10 +2,7 @@ Appellation: store Contrib: FL03 */ -#[cfg(all(feature = "alloc", no_std))] -use alloc::collections::{btree_map, BTreeMap}; -#[cfg(feature = "std")] -use std::collections::{btree_map, BTreeMap}; +#![allow(unused_macros)] pub trait Entry<'a> { type Key; @@ -80,10 +77,10 @@ macro_rules! impl_store { }; } -#[cfg(any(feature = "alloc", feature = "std"))] -impl_entry!(btree_map where K: Ord); -#[cfg(any(feature = "alloc", feature = "std"))] -impl_store!(BTreeMap, where K: Ord); +#[cfg(feature = "alloc")] +impl_entry!(alloc::collections::btree_map where K: Ord); +#[cfg(feature = "alloc")] +impl_store!(alloc::collections::BTreeMap, where K: Ord); #[cfg(feature = "std")] impl_entry!(std::collections::hash_map where K: Eq + core::hash::Hash); diff --git a/core/src/time/datetime.rs b/core/src/time/datetime.rs index 7c666078..ae1e630a 100644 --- a/core/src/time/datetime.rs +++ b/core/src/time/datetime.rs @@ -3,9 +3,20 @@ Contrib: FL03 */ -pub struct Date; +pub struct Date { + pub day: u8, + pub month: u8, + pub year: u16, +} -pub struct Time {} +pub struct Time { + pub hour: u8, + pub minute: u8, + pub second: u8, + pub millisecond: u16, + pub microsecond: u16, + pub nanosecond: u16, +} pub struct DateTime { pub date: Date, diff --git a/core/src/time/epoch.rs b/core/src/time/epoch.rs index 80c1e447..8b01ae26 100644 --- a/core/src/time/epoch.rs +++ b/core/src/time/epoch.rs @@ -2,22 +2,31 @@ Appellation: epoch Contrib: FL03 */ +use super::Timestamp; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub struct Epoch { +pub struct Epoch { size: u128, - timestamp: i64, + timestamp: Timestamp, } -impl Epoch { - pub fn new(size: u128, timestamp: i64) -> Self { +impl Epoch { + pub fn new(size: u128, timestamp: Timestamp) -> Self { Self { size, timestamp } } + /// The size of the epoch; epochs generally consider the number of steps, or size, + /// (e.g. the number of seconds) that will need to be taken before the epoch is considered + /// to be complete and a new one begins. pub fn size(&self) -> u128 { self.size } - pub fn timestamp(&self) -> i64 { - self.timestamp + + pub fn timestamp(&self) -> &T { + &self.timestamp + } + + pub fn set_size(&mut self, size: u128) { + self.size = size; } } diff --git a/core/src/time/mod.rs b/core/src/time/mod.rs index 64a21449..3a665ff8 100644 --- a/core/src/time/mod.rs +++ b/core/src/time/mod.rs @@ -3,25 +3,45 @@ Contrib: FL03 */ //! # Time -pub use self::{datetime::*, epoch::*, timestamp::*, utils::*}; +//! +//! The `time` module provides a set of utilities for working with time and timestamps. +#[allow(unused_imports)] +#[doc(inline)] +pub use self::{epoch::Epoch, timestamp::Timestamp, utils::*}; -pub(crate) mod datetime; -pub(crate) mod epoch; -pub(crate) mod timestamp; +#[doc(hidden)] +pub mod datetime; +pub mod epoch; +pub mod timestamp; -/// Interface for time-related data-structures -pub trait Temporal { - type Timestamp; +pub(crate) mod prelude { + pub use super::epoch::Epoch; + pub use super::timestamp::Timestamp; + #[allow(unused_imports)] + pub use super::utils::*; + pub use super::Now; +} + +/// +pub trait Now { + type Output; - fn timestamp(&self) -> Self::Timestamp; + fn now() -> Self::Output; } pub(crate) mod utils { - /// [systime] is a utilitarian function that returns the current system time in milliseconds. #[cfg(feature = "std")] #[inline] - pub fn systime() -> u128 { + pub fn systime() -> core::time::Duration { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + } + /// [systime] is a utilitarian function that returns the current system time in milliseconds. + #[cfg(feature = "std")] + #[inline] + pub fn std_time() -> u128 { std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() @@ -29,16 +49,33 @@ pub(crate) mod utils { } } +#[allow(unused)] #[cfg(test)] mod tests { use super::*; + use core::time::Duration; + fn absdiff(a: A, b: B) -> C + where + A: PartialOrd + core::ops::Sub, + B: core::ops::Sub, + { + if a > b { + a - b + } else { + b - a + } + } + + #[cfg(feature = "std")] #[test] - fn test_systime() { - let start = systime(); - std::thread::sleep(std::time::Duration::from_secs(1)); - let end = systime(); - assert!(end > start); + fn test_timestamp() { + let now = systime(); + let ts = Timestamp::::now(); + + let tsd = Duration::from_millis(ts.0 as u64); + let diff = absdiff(tsd, now).as_millis(); + assert!(diff < 1); } } diff --git a/core/src/time/timestamp.rs b/core/src/time/timestamp.rs index a1235b03..e51fc854 100644 --- a/core/src/time/timestamp.rs +++ b/core/src/time/timestamp.rs @@ -2,101 +2,173 @@ Appellation: timestamp Contrib: FL03 */ -use core::borrow::Borrow; -use core::ops::Deref; +use crate::time::Now; +use core::time::Duration; -/// Timestamp implements a host of useful utilities for stamping data +/// [Timestamp] is a generic type used to represent a timestamp. +/// +/// The timestamp considers the standard timestamp to be the #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -#[repr(transparent)] -pub struct Timestamp(u128); +pub struct Timestamp(pub T); -impl Timestamp { - pub fn new(timestamp: u128) -> Self { - Self(timestamp) +impl Timestamp { + pub fn new(ts: T) -> Self { + Self(ts) + } + /// Get the current timestamp. + pub fn now() -> Self + where + Self: Now, + { + ::now() + } + /// Get an immutable reference to the current timestamp. + pub fn as_ref(&self) -> &T { + &self.0 + } + /// Get a mutable reference to the current timestamp. + pub fn as_mut(&mut self) -> &mut T { + &mut self.0 + } + /// Get the current timestamp. + pub fn get(self) -> T { + self.0 + } + /// Replace the current timestamp with a new one. + pub fn replace(&mut self, ts: T) -> T { + core::mem::replace(&mut self.0, ts) + } + /// Set the current timestamp to a new value. + pub fn set(&mut self, ts: T) { + self.0 = ts; + } + /// Take the current timestamp and replace it with the default value. + pub fn take(&mut self) -> T + where + T: Default, + { + core::mem::take(&mut self.0) } - /// Create a new timestamp - #[cfg(feature = "std")] - pub fn now() -> Self { - Self(crate::time::systime()) + pub fn update(&mut self, ts: T) { + self.0 = ts; } +} - pub const fn get(&self) -> u128 { - self.0 +impl Default for Timestamp +where + Self: Now, +{ + fn default() -> Self { + Self::now() } } -impl AsRef for Timestamp { - fn as_ref(&self) -> &u128 { +#[cfg(feature = "std")] +impl Now for Timestamp { + type Output = Self; + + fn now() -> Self::Output { + Self::new(super::systime().as_secs()) + } +} + +#[cfg(feature = "std")] +impl Now for Timestamp { + type Output = Self; + + fn now() -> Self::Output { + Self::new(super::systime().as_millis()) + } +} + +#[cfg(feature = "chrono")] +impl Now for Timestamp { + type Output = Self; + + fn now() -> Self::Output { + Self::new(chrono::Local::now().timestamp()) + } +} + +impl AsRef for Timestamp { + fn as_ref(&self) -> &T { &self.0 } } -impl Borrow for Timestamp { - fn borrow(&self) -> &u128 { +impl AsMut for Timestamp { + fn as_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +impl core::borrow::Borrow for Timestamp { + fn borrow(&self) -> &T { &self.0 } } -impl Default for Timestamp { - fn default() -> Self { - Self::now() +impl core::borrow::BorrowMut for Timestamp { + fn borrow_mut(&mut self) -> &mut T { + &mut self.0 } } -impl Deref for Timestamp { - type Target = u128; +impl core::ops::Deref for Timestamp { + type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } -impl From for Timestamp { - fn from(timestamp: u128) -> Self { - Self(timestamp) +impl core::ops::DerefMut for Timestamp { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 } } -impl From for u128 { - fn from(timestamp: Timestamp) -> Self { - timestamp.0 +impl core::fmt::Display for Timestamp +where + T: core::fmt::Display, +{ + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", self.0) } } -macro_rules! fmt_timestamp { - ($($t:ident($($rest:tt)*)),*) => { - $( - impl core::fmt::$t for Timestamp { - fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - write!(f, $($rest)*, self.0) - } - } - )* - }; +impl From for Timestamp { + fn from(dur: Duration) -> Self { + Self(dur.as_secs()) + } } -fmt_timestamp! { - Binary("{:b}"), - Display("{}"), - LowerExp("{:e}"), - LowerHex("{:x}"), - Octal("{:o}"), - UpperExp("{:E}"), - UpperHex("{:X}") +impl From for Timestamp { + fn from(dur: Duration) -> Self { + Self(dur.as_millis()) + } } -#[cfg(test)] -mod tests { - use super::*; +#[cfg(feature = "chrono")] +impl From> for Timestamp +where + Tz: chrono::TimeZone, +{ + fn from(ts: chrono::DateTime) -> Self { + Self(ts.timestamp()) + } +} + +impl From> for Duration { + fn from(ts: Timestamp) -> Self { + Self::from_secs(*ts) + } +} - #[test] - fn test_timestamp() { - let a = Timestamp::now(); - std::thread::sleep(std::time::Duration::from_secs(1)); - let b = Timestamp::now(); - assert_ne!(a, b); - assert!(a < b); +impl From> for Duration { + fn from(ts: Timestamp) -> Self { + Self::from_millis(*ts as u64) } } diff --git a/core/src/traits/appellation.rs b/core/src/traits/appellation.rs index cefeb474..d0331e55 100644 --- a/core/src/traits/appellation.rs +++ b/core/src/traits/appellation.rs @@ -2,10 +2,8 @@ Appellation: appellation Contrib: FL03 */ -#![cfg(any(feature = "std", all(feature = "alloc", no_std)))] -use crate::prelude::{Classifier, Identifier}; -#[cfg(all(feature = "alloc", no_std))] -use alloc::string::String; +use crate::id::Identifier; +use crate::traits::Classifier; /// An appellation is considered to be a name or title that is used to identify an object. /// For our purposes, an `Appellation` is a type that is used to identify an object in a computational space. @@ -19,11 +17,7 @@ pub trait Appellation { fn id(&self) -> &Self::Id; - fn name(&self) -> String; - - fn slug(&self) -> String { - self.name().to_lowercase().replace(" ", "-") - } + fn name(&self) -> &str; } /* @@ -33,7 +27,7 @@ impl Appellation for (Cls, Id, T) where Cls: Classifier, Id: Identifier, - T: ToString, + T: AsRef, { type Class = Cls; type Id = Id; @@ -46,7 +40,7 @@ where &self.1 } - fn name(&self) -> String { - self.2.to_string() + fn name(&self) -> &str { + self.2.as_ref() } } diff --git a/core/src/traits/classify.rs b/core/src/traits/classify.rs index eea9a4d9..1a869f71 100644 --- a/core/src/traits/classify.rs +++ b/core/src/traits/classify.rs @@ -2,8 +2,6 @@ Appellation: classify Contrib: FL03 */ -#[cfg(all(feature = "alloc", no_std))] -use alloc::string::String; /// Interface for classifiable objects pub trait Classifiable { @@ -28,5 +26,5 @@ macro_rules! classifier { classifier!(f32, f64, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, &str, char); -#[cfg(any(feature = "alloc", feature = "std"))] -classifier!(String); +#[cfg(feature = "alloc")] +classifier!(alloc::string::String); diff --git a/core/src/traits/dtype.rs b/core/src/traits/dtype.rs index 5789e666..26853733 100644 --- a/core/src/traits/dtype.rs +++ b/core/src/traits/dtype.rs @@ -2,7 +2,7 @@ Appellation: dtype Contrib: FL03 */ -use crate::type_of; +use crate::utils::type_of; use core::any::{Any, TypeId}; pub trait IsType: 'static { diff --git a/core/src/traits/ext/string.rs b/core/src/traits/ext/string.rs index d3eb5587..cd4b484c 100644 --- a/core/src/traits/ext/string.rs +++ b/core/src/traits/ext/string.rs @@ -2,8 +2,8 @@ Appellation: string Contrib: FL03 */ -#![cfg(any(feature = "std", all(feature = "alloc", no_std)))] -#[cfg(all(feature = "alloc", no_std))] +#![cfg(feature = "alloc")] + use alloc::string::String; pub trait StringExt { diff --git a/core/src/traits/mod.rs b/core/src/traits/mod.rs index 52ba2fe1..a4fc3814 100644 --- a/core/src/traits/mod.rs +++ b/core/src/traits/mod.rs @@ -2,6 +2,7 @@ Appellation: traits Contrib: FL03 */ +#[doc(inline)] pub use self::prelude::*; pub mod adjust; @@ -11,16 +12,24 @@ pub mod dtype; pub mod toggle; pub mod ext { - pub use self::prelude::*; + pub use self::slice::*; + #[cfg(feature = "alloc")] + pub use self::string::*; - pub(crate) mod slice; - pub(crate) mod string; + mod slice; + mod string; - pub(crate) mod prelude { - pub use super::slice::*; - #[cfg(any(feature = "alloc", feature = "std"))] - pub use super::string::*; - } + pub(crate) mod prelude {} +} + +pub(crate) mod prelude { + pub use super::adjust::*; + pub use super::appellation::*; + pub use super::classify::*; + pub use super::dtype::*; + pub use super::ext::*; + pub use super::toggle::*; + pub use super::{IntoInner, Name}; } /// [IntoInner] is typically used for basic structures that wrap a single value. @@ -31,24 +40,6 @@ pub trait IntoInner { } /// Interface for nameable data-structures -#[cfg(any(feature = "std", all(feature = "alloc", no_std)))] pub trait Name { fn name(&self) -> &str; - - fn slug(&self) -> String { - self.name().to_lowercase().replace(" ", "-") - } -} - -pub(crate) mod prelude { - pub use super::adjust::*; - #[cfg(any(feature = "alloc", feature = "std"))] - pub use super::appellation::*; - pub use super::classify::*; - pub use super::dtype::*; - pub use super::ext::prelude::*; - pub use super::toggle::*; - pub use super::IntoInner; - #[cfg(any(feature = "alloc", feature = "std"))] - pub use super::Name; } diff --git a/core/src/types/mod.rs b/core/src/types/mod.rs index d0a33a6b..71d33727 100644 --- a/core/src/types/mod.rs +++ b/core/src/types/mod.rs @@ -2,10 +2,60 @@ Appellation: types Contrib: FL03 */ +#[doc(inline)] pub use self::direction::Direction; +#[cfg(feature = "std")] +#[doc(inline)] +pub use self::std_types::*; pub mod direction; pub(crate) mod prelude { pub use super::direction::Direction; + #[cfg(feature = "std")] + pub use super::std_types::*; +} + +#[cfg(feature = "std")] +mod std_types { + /// Type alias for async errors + pub type AsyncError = Box; + /// Type alias for async results + pub type AsyncResult = core::result::Result; + /// Type alias for a boxed error with send, sync, and static flags enabled + pub type BoxError = Box; + /// Type alias for the standard result used + pub type BoxResult = core::result::Result; + /// Type alias wrapping a locked, thread-safe structure with a [Mutex] in an [Arc] + pub type Arcm = std::sync::Arc>; + /// Type alias for [std::io::Result] + pub type IOResult = std::io::Result; +} + +#[allow(unused_imports)] +pub(crate) mod rs { + pub(crate) use core::*; + + #[cfg(all(feature = "alloc", no_std))] + pub(crate) use self::no_std::*; + #[cfg(feature = "std")] + pub(crate) use self::std_ty::*; + + #[cfg(feature = "alloc")] + pub(crate) mod no_std { + pub(crate) use alloc::boxed::{self, Box}; + pub(crate) use alloc::collections::{self, BTreeMap, BTreeSet}; + pub(crate) use alloc::string::{self, String, ToString}; + pub(crate) use alloc::sync::{self, Arc}; + pub(crate) use alloc::vec::{self, Vec}; + } + + #[cfg(feature = "std")] + pub(crate) mod std_ty { + pub(crate) use std::boxed::{self, Box}; + pub(crate) use std::collections::{self, BTreeMap, BTreeSet}; + pub(crate) use std::string::{self, String, ToString}; + pub(crate) use std::sync::{self, Arc}; + pub(crate) use std::vec::{self, Vec}; + } } diff --git a/core/src/utils.rs b/core/src/utils.rs index 963c66b0..938f6af1 100644 --- a/core/src/utils.rs +++ b/core/src/utils.rs @@ -2,72 +2,21 @@ Appellation: utils Contrib: FL03 */ +#[cfg(feature = "alloc")] +pub use self::alloc::*; #[cfg(feature = "std")] -pub use self::std_utils::*; -#[cfg(all(feature = "alloc", no_std))] -pub use alloc::string::String; -use core::any::{Any, TypeId}; +pub use self::std::*; -pub(crate) mod std_utils; +#[cfg(feature = "alloc")] +mod alloc; +#[cfg(feature = "std")] +mod std; /// Compare two types pub fn type_of() -> bool where - U: Any + ?Sized, - V: Any + ?Sized, + U: core::any::Any + ?Sized, + V: core::any::Any + ?Sized, { - TypeId::of::() == TypeId::of::() -} - -/// Remove the first and last charecters of a string -pub fn fnl_remove(data: impl ToString) -> String { - let data = data.to_string(); - let mut chars = data.chars(); - chars.next(); - chars.next_back(); - chars.as_str().to_string() -} - -pub fn snakecase(name: impl ToString) -> String { - let data = name.to_string(); - - let mut buffer = String::with_capacity(data.len() + data.len() / 2); - - let mut text = data.chars(); - - if let Some(first) = text.next() { - let mut n2: Option<(bool, char)> = None; - let mut n1: (bool, char) = (first.is_lowercase(), first); - - for c in text { - let prev_n1 = n1.clone(); - - let n3 = n2; - n2 = Some(n1); - n1 = (c.is_lowercase(), c); - - // insert underscore if acronym at beginning - // ABc -> a_bc - if n1.0 - && matches!(n2, Some((false, _))) - && matches!(n3, Some((false, _))) - && n2.unwrap().1.is_uppercase() - && n3.unwrap().1.is_uppercase() - { - buffer.push('_'); - } - - buffer.push_str(&prev_n1.1.to_lowercase().to_string()); - - // insert underscore before next word - // abC -> ab_c - if matches!(n2, Some((true, _))) && n1.1.is_uppercase() { - buffer.push('_'); - } - } - - buffer.push_str(&n1.1.to_lowercase().to_string()); - } - - buffer + core::any::TypeId::of::() == core::any::TypeId::of::() } diff --git a/core/src/utils/alloc.rs b/core/src/utils/alloc.rs new file mode 100644 index 00000000..bd525a9f --- /dev/null +++ b/core/src/utils/alloc.rs @@ -0,0 +1,58 @@ +/* + Appellation: alloc + Contrib: FL03 +*/ + +use alloc::string::String; +/// Remove the first and last charecters of a string +pub fn fnl_remove(data: impl ToString) -> String { + let data = data.to_string(); + let mut chars = data.chars(); + chars.next(); + chars.next_back(); + chars.as_str().to_string() +} +/// Convert a string to snakecase +pub fn snakecase(name: impl ToString) -> String { + let data = name.to_string(); + + let mut buffer = String::with_capacity(data.len() + data.len() / 2); + + let mut text = data.chars(); + + if let Some(first) = text.next() { + let mut n2: Option<(bool, char)> = None; + let mut n1: (bool, char) = (first.is_lowercase(), first); + + for c in text { + let prev_n1 = n1.clone(); + + let n3 = n2; + n2 = Some(n1); + n1 = (c.is_lowercase(), c); + + // insert underscore if acronym at beginning + // ABc -> a_bc + if n1.0 + && matches!(n2, Some((false, _))) + && matches!(n3, Some((false, _))) + && n2.unwrap().1.is_uppercase() + && n3.unwrap().1.is_uppercase() + { + buffer.push('_'); + } + + buffer.push_str(&prev_n1.1.to_lowercase().to_string()); + + // insert underscore before next word + // abC -> ab_c + if matches!(n2, Some((true, _))) && n1.1.is_uppercase() { + buffer.push('_'); + } + } + + buffer.push_str(&n1.1.to_lowercase().to_string()); + } + + buffer +} diff --git a/core/src/utils/std_utils.rs b/core/src/utils/std.rs similarity index 93% rename from core/src/utils/std_utils.rs rename to core/src/utils/std.rs index 0e0049b5..0b8c7d4f 100644 --- a/core/src/utils/std_utils.rs +++ b/core/src/utils/std.rs @@ -1,3 +1,7 @@ +/* + Appellation: std_utils + Contrib: FL03 +*/ #![cfg(feature = "std")] pub use self::fs::*; From 1dac74254f15c499cba578e1686924c962932fa5 Mon Sep 17 00:00:00 2001 From: FL03 Date: Sun, 22 Sep 2024 11:40:48 -0500 Subject: [PATCH 14/18] update Signed-off-by: FL03 --- .github/dependabot.yml | 6 ++- Cargo.toml | 3 +- core/Cargo.toml | 1 + core/src/lib.rs | 4 -- core/src/name/casing.rs | 39 --------------- core/src/name/mod.rs | 15 ------ core/src/utils/alloc.rs | 44 ----------------- scsys/Cargo.toml | 21 ++++++-- utils/Cargo.toml | 101 +++++++++++++++++++++++++++++++++++++++ utils/src/casing/kind.rs | 51 ++++++++++++++++++++ utils/src/casing/mod.rs | 86 +++++++++++++++++++++++++++++++++ utils/src/lib.rs | 20 ++++++++ utils/tests/casing.rs | 12 +++++ utils/tests/default.rs | 17 +++++++ 14 files changed, 313 insertions(+), 107 deletions(-) delete mode 100644 core/src/name/casing.rs delete mode 100644 core/src/name/mod.rs create mode 100644 utils/Cargo.toml create mode 100644 utils/src/casing/kind.rs create mode 100644 utils/src/casing/mod.rs create mode 100644 utils/src/lib.rs create mode 100644 utils/tests/casing.rs create mode 100644 utils/tests/default.rs diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 74833381..ad88faeb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,6 +8,10 @@ updates: directory: / schedule: interval: monthly + - package-ecosystem: cargo + directory: /scsys + schedule: + interval: weekly - package-ecosystem: cargo directory: /actors schedule: @@ -25,6 +29,6 @@ updates: schedule: interval: weekly - package-ecosystem: cargo - directory: /scsys + directory: /utils schedule: interval: weekly diff --git a/Cargo.toml b/Cargo.toml index b21adf50..ea719b4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,8 @@ members = [ "core", "derive", "macros", - "scsys", + "scsys", + "utils", ] resolver = "2" diff --git a/core/Cargo.toml b/core/Cargo.toml index d6e22191..7184c414 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -20,6 +20,7 @@ default = [ full = [ "default", + "chrono", "rand", "serde", ] diff --git a/core/src/lib.rs b/core/src/lib.rs index 0ca5ccb4..56bc9f77 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -26,8 +26,6 @@ pub mod errors; pub mod hkt; pub mod id; #[doc(hidden)] -pub mod name; -#[doc(hidden)] pub mod stores; pub mod sync; pub mod time; @@ -40,8 +38,6 @@ pub mod prelude { pub use crate::errors::prelude::*; pub use crate::id::prelude::*; #[doc(hidden)] - pub use crate::name::prelude::*; - #[doc(hidden)] pub use crate::stores::prelude::*; pub use crate::sync::prelude::*; pub use crate::time::prelude::*; diff --git a/core/src/name/casing.rs b/core/src/name/casing.rs deleted file mode 100644 index cfae9ae9..00000000 --- a/core/src/name/casing.rs +++ /dev/null @@ -1,39 +0,0 @@ -/* - Appellation: convention - Contrib: FL03 -*/ -use strum::{ - AsRefStr, Display, EnumCount, EnumIs, EnumIter, EnumString, VariantArray, VariantNames, -}; - -#[derive( - AsRefStr, - Clone, - Copy, - Debug, - Display, - EnumCount, - EnumIs, - EnumIter, - EnumString, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - VariantArray, - VariantNames, -)] -#[cfg_attr( - feature = "serde", - derive(serde::Deserialize, serde::Serialize,), - serde(rename_all = "snake_case") -)] -#[repr(u8)] -#[strum(serialize_all = "snake_case")] -pub enum CaseType { - CamelCase, - KebabCase, - PascalCase, - SnakeCase, -} diff --git a/core/src/name/mod.rs b/core/src/name/mod.rs deleted file mode 100644 index ad97ba85..00000000 --- a/core/src/name/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -/* - Appellation: name - Contrib: FL03 -*/ -//! # Name -//! -//! This module works to implement various naming conventions and name-related primitives. -#[doc(inline)] -pub use self::casing::*; - -pub(crate) mod casing; - -pub(crate) mod prelude { - pub use super::casing::CaseType; -} diff --git a/core/src/utils/alloc.rs b/core/src/utils/alloc.rs index bd525a9f..8bc43a02 100644 --- a/core/src/utils/alloc.rs +++ b/core/src/utils/alloc.rs @@ -12,47 +12,3 @@ pub fn fnl_remove(data: impl ToString) -> String { chars.next_back(); chars.as_str().to_string() } -/// Convert a string to snakecase -pub fn snakecase(name: impl ToString) -> String { - let data = name.to_string(); - - let mut buffer = String::with_capacity(data.len() + data.len() / 2); - - let mut text = data.chars(); - - if let Some(first) = text.next() { - let mut n2: Option<(bool, char)> = None; - let mut n1: (bool, char) = (first.is_lowercase(), first); - - for c in text { - let prev_n1 = n1.clone(); - - let n3 = n2; - n2 = Some(n1); - n1 = (c.is_lowercase(), c); - - // insert underscore if acronym at beginning - // ABc -> a_bc - if n1.0 - && matches!(n2, Some((false, _))) - && matches!(n3, Some((false, _))) - && n2.unwrap().1.is_uppercase() - && n3.unwrap().1.is_uppercase() - { - buffer.push('_'); - } - - buffer.push_str(&prev_n1.1.to_lowercase().to_string()); - - // insert underscore before next word - // abC -> ab_c - if matches!(n2, Some((true, _))) && n1.1.is_uppercase() { - buffer.push('_'); - } - } - - buffer.push_str(&n1.1.to_lowercase().to_string()); - } - - buffer -} diff --git a/scsys/Cargo.toml b/scsys/Cargo.toml index beffca38..70496b15 100644 --- a/scsys/Cargo.toml +++ b/scsys/Cargo.toml @@ -23,9 +23,10 @@ full = [ "rand", "serde", "tokio", + "utils", ] -# *** [FF] Crates *** +# ********* [FF] Packages ********* actors = [ "dep:scsys-actors", @@ -40,10 +41,15 @@ macros = [ "dep:scsys-macros", ] +utils = [ + "dep:scsys-utils", +] + # *** [FF] Dependencies *** alloc = [ - "scsys-actors?/alloc", "scsys-core/alloc", + "scsys-actors?/alloc", + "scsys-utils?/alloc", ] rand = [ "scsys-core/rand", @@ -60,8 +66,9 @@ tokio = [ # *** [FF] Environments *** std = [ - "scsys-actors?/std", "scsys-core/std", + "scsys-actors?/std", + "scsys-utils?/std", ] wasi = [ @@ -96,11 +103,13 @@ required-features = ["derive"] [build-dependencies] [dependencies.scsys-actors] +default-features = false optional = true path = "../actors" version = "0.2.3" [dependencies.scsys-core] +default-features = false path = "../core" version = "0.2.3" @@ -114,6 +123,12 @@ optional = true path = "../macros" version = "0.2.3" +[dependencies.scsys-utils] +default-features = false +optional = true +path = "../utils" +version = "0.2.3" + [dev-dependencies] serde = { features = ["derive"], version = "1" } serde_json = "1" diff --git a/utils/Cargo.toml b/utils/Cargo.toml new file mode 100644 index 00000000..c98799f5 --- /dev/null +++ b/utils/Cargo.toml @@ -0,0 +1,101 @@ +[package] +name = "scsys-utils" +authors.workspace = true +categories.workspace = true +description.workspace = true +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true +version.workspace = true + +[features] +default = [ + "std" +] + +full = [ + "default", + "rand", + "serde", +] + +# ******* [FF] Dependencies ******* +alloc = [ + "num/alloc", + "rand?/alloc", + "serde?/alloc", +] + +rand = [ + "dep:rand", + "num/rand", +] + +serde = [ + "dep:serde", + "serde-ext", +] + +serde-ext = [ + "num/serde", + "rand?/serde1", +] + +# ******* [FF] Environment ******* +std = [ + "alloc", + "num/std", + "rand?/std", + "rand?/std_rng", + "serde?/std", + "strum/std", +] + +wasi = [] + +wasm = [ + "getrandom/js", +] + +[lib] +bench = false +crate-type = ["cdylib", "rlib"] +doctest = true +test = true + +[[test]] +name = "casing" +required-features = ["alloc"] + +[build-dependencies] + +[dev-dependencies] +anyhow = "1" +serde_json = "1" + +[dependencies] +num.workspace = true +strum.workspace = true + + +[dependencies.rand] +default-features = false +optional = true +version = "0.8" + +[dependencies.serde] +default-features = false +features = ["derive"] +optional = true +version = "1" + +[package.metadata.docs.rs] +rustc-args = ["--cfg", "docsrs"] + +[target.wasm32-unknown-unknown.dependencies] +getrandom = "0.2" + +[target.wasm32-wasi] diff --git a/utils/src/casing/kind.rs b/utils/src/casing/kind.rs new file mode 100644 index 00000000..6162ba81 --- /dev/null +++ b/utils/src/casing/kind.rs @@ -0,0 +1,51 @@ +/* + Appellation: convention + Contrib: FL03 +*/ + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + strum::AsRefStr, + strum::Display, + strum::EnumCount, + strum::EnumIs, + strum::EnumIter, + strum::EnumString, + strum::VariantArray, + strum::VariantNames, +)] +#[cfg_attr( + feature = "serde", + derive(serde::Deserialize, serde::Serialize,), + serde(rename_all = "snake_case") +)] +#[strum(serialize_all = "snake_case")] +pub enum CaseType { + CamelCase, + KebabCase, + PascalCase, + #[default] + SnakeCase, +} + +impl CaseType { + #[cfg(feature = "alloc")] + /// Converts a string to the specified case. + pub fn convert(&self, s: &str) -> alloc::string::String { + use super::utils; + match self { + Self::CamelCase => utils::to_camelcase(s), + Self::KebabCase => utils::to_kebabcase(s), + Self::PascalCase => utils::to_pascalcase(s), + Self::SnakeCase => utils::to_snakecase(s), + } + } +} diff --git a/utils/src/casing/mod.rs b/utils/src/casing/mod.rs new file mode 100644 index 00000000..9610efc6 --- /dev/null +++ b/utils/src/casing/mod.rs @@ -0,0 +1,86 @@ +/* + Appellation: casing + Contrib: FL03 +*/ +//! # Casing +//! +//! This module works to implement various naming conventions and name-related primitives. +#![cfg(feature = "alloc")] +#[doc(inline)] +pub use self::{kind::*, utils::*}; + +mod kind; + +pub(crate) mod prelude { + pub use super::kind::CaseType; +} + +mod utils { + #[cfg(feature = "alloc")] + use alloc::string::String; + + /// Converts a string to snake_case. + pub fn to_snakecase(s: &str) -> String { + s.chars() + .fold(String::new(), |mut acc, c| { + if c.is_uppercase() { + if !acc.is_empty() { + acc.push('_'); + } + acc.push(c.to_lowercase().next().unwrap()); + } else { + acc.push(c); + } + acc + }) + .to_lowercase() + } + + /// Converts a string to camelCase. + pub fn to_camelcase(s: &str) -> String { + let mut chars = s.chars(); + let first = chars.next().unwrap(); + let rest = chars.collect::(); + format!("{}{}", first.to_lowercase(), rest) + } + + /// Converts a string to PascalCase. + pub fn to_pascalcase(s: &str) -> String { + let mut chars = s.chars(); + let first = chars.next().unwrap(); + let rest = chars.collect::(); + format!("{}{}", first.to_uppercase(), rest) + } + + /// Converts a string to kebab-case. + pub fn to_kebabcase(s: &str) -> String { + s.chars() + .fold(String::new(), |mut acc, c| { + if c.is_uppercase() { + if !acc.is_empty() { + acc.push('-'); + } + acc.push(c.to_lowercase().next().unwrap()); + } else { + acc.push(c); + } + acc + }) + .to_lowercase() + } + + /// Converts a string to SCREAMING_SNAKE_CASE. + pub fn to_screaming_snakecase(s: &str) -> String { + s.chars().fold(String::new(), |mut acc, c| { + if c.is_uppercase() { + if !acc.is_empty() { + acc.push('_'); + } + acc.push(c); + } else { + acc.push(c.to_uppercase().next().unwrap()); + } + acc + }) + } +} diff --git a/utils/src/lib.rs b/utils/src/lib.rs new file mode 100644 index 00000000..6b21e08c --- /dev/null +++ b/utils/src/lib.rs @@ -0,0 +1,20 @@ +/* + Appellation: scsys-utils + Contrib: FL03 +*/ +//! # Utils +//! + +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(feature = "alloc")] +#[doc(inline)] +pub use self::casing::*; + +pub mod casing; + +#[allow(unused_imports)] +pub mod prelude { + pub use crate::casing::prelude::*; +} diff --git a/utils/tests/casing.rs b/utils/tests/casing.rs new file mode 100644 index 00000000..e17d465a --- /dev/null +++ b/utils/tests/casing.rs @@ -0,0 +1,12 @@ +/* + Appellation: casing + Contrib: FL03 +*/ +use scsys_utils::casing::to_snakecase; + +#[test] +fn test_snakecase() { + let s = "HelloWorld"; + + assert_eq!(to_snakecase(s), "hello_world"); +} diff --git a/utils/tests/default.rs b/utils/tests/default.rs new file mode 100644 index 00000000..6353d6be --- /dev/null +++ b/utils/tests/default.rs @@ -0,0 +1,17 @@ +/* + Appellation: default + Contrib: FL03 +*/ + +fn addition(a: A, b: B) -> C +where + A: core::ops::Add, +{ + a + b +} + +#[test] +fn compiles() { + assert_eq!(addition(1, 2), 3); + assert_ne!(addition(1f64, 0f64), 3f64); +} From 29021dac74d7da4b69361091f6c385eefb2314d8 Mon Sep 17 00:00:00 2001 From: FL03 Date: Sun, 22 Sep 2024 11:49:13 -0500 Subject: [PATCH 15/18] update Signed-off-by: FL03 --- .github/workflows/crates.yml | 43 +++++++++++++++++++++++++----------- .github/workflows/rust.yml | 10 +++++---- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/.github/workflows/crates.yml b/.github/workflows/crates.yml index 3bbf4282..482de608 100644 --- a/.github/workflows/crates.yml +++ b/.github/workflows/crates.yml @@ -5,6 +5,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} CARGO_TERM_COLOR: always on: @@ -16,27 +17,43 @@ on: jobs: core: + env: + PACKAGE: ${{ github.event.repository.name }}-${{ matrix.package }} runs-on: ubuntu-latest + strategy: + matrix: + package: [ core ] steps: - - uses: actions/checkout@v4 - - name: publish - run: cargo publish --all-features -v -p ${{ github.event.repository.name }}-core --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + - + name: checkout + uses: actions/checkout@v4 + - + name: publish (${{ matrix.package }}) + run: cargo publish --all-features -v -p ${{ env.PACKAGE }} features: + env: + PACKAGE: ${{ github.event.repository.name }}-${{ matrix.package }} needs: core runs-on: ubuntu-latest strategy: matrix: - package: [ actors, derive, macros, ] - env: - PACKAGE_NAME: ${{ github.event.repository.name }}-${{ matrix.package }} + package: [ actors, derive, macros, utils ] steps: - - uses: actions/checkout@v4 - - name: publish (${{ env.PACKAGE_NAME }}) - run: cargo publish --all-features -v -p ${{ env.PACKAGE_NAME }} --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + - + name: checkout + uses: actions/checkout@v4 + - + name: publish (${{ matrix.package }}) + run: cargo publish --all-features -v -p ${{ env.PACKAGE }} sdk: - needs: features + env: + PACKAGE: ${{ github.event.repository.name }} + needs: [ core, features ] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: publish - run: cargo publish --all-features -v -p ${{ github.event.repository.name }} --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + - + name: checkout + uses: actions/checkout@v4 + - + name: publish + run: cargo publish --all-features -v -p ${{ env.PACKAGE }} diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1708b3b7..76afbd53 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,7 +1,7 @@ name: Rust concurrency: - cancel-in-progress: true + cancel-in-progress: false group: ${{ github.workflow }}-${{ github.ref }} env: @@ -39,6 +39,10 @@ jobs: - name: test run: cargo test --all-features -r -v --workspace --target ${{ matrix.target }} + - + continue-on-error: true + name: Test (no_std) + run: cargo test --no-default-features -p scsys-core -r -v - name: bench if: matrix.toolchain == 'nightly' @@ -72,7 +76,5 @@ jobs: - name: rustup run: rustup default ${{ matrix.toolchain }} && rustup update - - - name: Test (${{ matrix.package }}) - run: cargo test --no-default-features -p ${{ matrix.package }} -r -v + From c4d89a26066169ae94fce4b571dbe116369b9270 Mon Sep 17 00:00:00 2001 From: FL03 Date: Sun, 22 Sep 2024 12:17:47 -0500 Subject: [PATCH 16/18] update Signed-off-by: FL03 --- .artifacts/docs/QUICKSTART.md | 11 - .artifacts/license/APACHE.LICENSE | 201 ------------------ .artifacts/license/MIT.LICENSE | 21 -- CONTRIBUTING.md | 0 README.md | 51 +++-- actors/src/lib.rs | 4 +- actors/src/state/kinds.rs | 19 -- actors/tests/states.rs | 1 - core/Cargo.toml | 1 + core/src/lib.rs | 9 +- .../src/state/interface.rs | 0 core/src/state/kinds.rs | 34 +++ {actors => core}/src/state/mod.rs | 22 +- core/tests/state.rs | 16 ++ scsys/Cargo.toml | 8 +- 15 files changed, 103 insertions(+), 295 deletions(-) delete mode 100644 .artifacts/docs/QUICKSTART.md delete mode 100644 .artifacts/license/APACHE.LICENSE delete mode 100644 .artifacts/license/MIT.LICENSE create mode 100644 CONTRIBUTING.md delete mode 100644 actors/src/state/kinds.rs delete mode 100644 actors/tests/states.rs rename actors/src/state/base_state.rs => core/src/state/interface.rs (100%) create mode 100644 core/src/state/kinds.rs rename {actors => core}/src/state/mod.rs (59%) create mode 100644 core/tests/state.rs diff --git a/.artifacts/docs/QUICKSTART.md b/.artifacts/docs/QUICKSTART.md deleted file mode 100644 index 8bfbfb1e..00000000 --- a/.artifacts/docs/QUICKSTART.md +++ /dev/null @@ -1,11 +0,0 @@ -# Quickstart - -## Building from the source - - git clone https://github.com/scattered-systems/scsys - cd scsys - -### *Cargo Commands* - - cargo build --release --workspace - cargo build --release --workspace --target wasm32-unknown-unknown diff --git a/.artifacts/license/APACHE.LICENSE b/.artifacts/license/APACHE.LICENSE deleted file mode 100644 index 622e1d93..00000000 --- a/.artifacts/license/APACHE.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2024 Scattered-Systems, LLC - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/.artifacts/license/MIT.LICENSE b/.artifacts/license/MIT.LICENSE deleted file mode 100644 index 941f8b8b..00000000 --- a/.artifacts/license/MIT.LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2024 Scattered-Systems, LLC - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..e69de29b diff --git a/README.md b/README.md index 5d863a36..cc415506 100644 --- a/README.md +++ b/README.md @@ -2,35 +2,46 @@ [![crates.io](https://img.shields.io/crates/v/scsys.svg)](https://crates.io/crates/scsys) [![docs](https://docs.rs/scsys/badge.svg)](https://docs.rs/scsys) +[![license](https://img.shields.io/crates/l/scsys.svg)](https://crates.io/crates/scsys) [![clippy](https://github.com/Scattered-Systems/scsys/actions/workflows/clippy.yml/badge.svg)](https://github.com/Scattered-Systems/scsys/actions/workflows/clippy.yml) [![rust](https://github.com/Scattered-Systems/scsys/actions/workflows/rust.yml/badge.svg)](https://github.com/Scattered-Systems/scsys/actions/workflows/rust.yml) *** -Welcome to scsys, this library provides a set of primitives and utilities used throughout the ecosystem. +_**Warning: the library is currently in development so be prepared for major modifications to the API!**_ +Welcome to `scsys`, a collection of useful utilities, types, and other primitives that are used in various projects developed by [Scattered Systems](https://github.com/scattered-systems). The library is designed to be a general-purpose utility library that can be used in any Rust project, aiming to provide a standardized set of tools that can be used to build robust and reliable software. -# Getting Started - -Use Rust's built-in package manager [crates](https://crates.io/crates/scsys) to install *scsys*. +## Getting Started ## Building from the source +Make sure you have the latest version of the Rust toolchain installed on your system. + +```bash +rustup update +``` + ### _Clone the repository_ ```bash -git clone https://github.com/scattered-systems/scsys +git clone https://github.com/scattered-systems/scsys.git +``` + +then, navigate to the project directory + +```bash cd scsys ``` -### _Build the workspace locally_ +### _Building Locally_ ```bash cargo build --all-features -v --workspace ``` -#### _Testing_ +### _Testing_ Automatically format and analyze the codebase before building then testing. @@ -38,11 +49,19 @@ Automatically format and analyze the codebase before building then testing. cargo test --all-features -r -v --workspace ``` -```bash -cargo test --all-features -r -v --workspace +### Usage + +#### _Add the dependency to your project_ + +```toml +[dependencies.scsys] +features = ["full"] +version = "0.2.*" ``` -# Usage +#### Examples + +##### _Example: Using the `Message` type_ ```rust use scsys::prelude::*; @@ -52,14 +71,10 @@ fn main() { } ``` -# Contributing - -Pull requests are welcome. For major changes, please open an issue first -to discuss what you would like to change. +## License -Please make sure to update tests as appropriate. +Licensed under the Apache License, Version 2.0, ([LICENSE-APACHE](http://www.apache.org/licenses/LICENSE-2.0)) -# License +## Contribution -- [Apache-2.0](https://choosealicense.com/licenses/apache-2.0/) -- [MIT](https://choosealicense.com/licenses/mit/) +Contributions are welcome, however, ensure that you have read the [CONTRIBUTING.md](CONTRIBUTING.md) file before submitting a pull request. diff --git a/actors/src/lib.rs b/actors/src/lib.rs index 1b4813a9..7d81e53a 100644 --- a/actors/src/lib.rs +++ b/actors/src/lib.rs @@ -12,7 +12,7 @@ extern crate alloc; extern crate scsys_core as scsys; -pub use self::{state::State, traits::*}; +pub use self::traits::*; pub(crate) mod actor; #[macro_use] @@ -20,7 +20,6 @@ pub(crate) mod macros; pub mod messages; pub mod power; -pub mod state; pub mod traits; pub type Job = Box; @@ -29,6 +28,5 @@ pub mod prelude { pub use crate::actor::*; pub use crate::messages::*; pub use crate::power::*; - pub use crate::state::prelude::*; pub use crate::traits::prelude::*; } diff --git a/actors/src/state/kinds.rs b/actors/src/state/kinds.rs deleted file mode 100644 index 49d7766c..00000000 --- a/actors/src/state/kinds.rs +++ /dev/null @@ -1,19 +0,0 @@ -/* - Appellation: binary - Contrib: FL03 -*/ -use super::State; - -pub enum Unary {} - -pub enum Binary {} - -pub enum Ternary {} - -pub enum Nary {} - -pub type BinaryState = State; - -pub type UnaryState = State; - -pub type NState = State, T>; diff --git a/actors/tests/states.rs b/actors/tests/states.rs deleted file mode 100644 index 8b137891..00000000 --- a/actors/tests/states.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/core/Cargo.toml b/core/Cargo.toml index 7184c414..c09d260f 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -86,6 +86,7 @@ serde_json = "1" [dependencies] glob = "0.3" num.workspace = true +paste = "1" smart-default.workspace = true strum.workspace = true diff --git a/core/src/lib.rs b/core/src/lib.rs index 56bc9f77..a0586ef6 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -4,15 +4,18 @@ */ //! # Core //! -//! +//! This library provides a set of common utilities, types, and other primitives used +//! throughout the ecosystem. #![cfg_attr(not(feature = "std"), no_std)] #[cfg(feature = "alloc")] extern crate alloc; -pub use self::{traits::prelude::*, types::prelude::*, utils::*}; +#[doc(inline)] +pub use self::{state::State, traits::prelude::*, types::prelude::*, utils::*}; #[cfg(feature = "alloc")] +#[doc(inline)] pub use self::errors::{Error, Errors, Result}; #[macro_use] @@ -25,6 +28,7 @@ pub(crate) mod utils; pub mod errors; pub mod hkt; pub mod id; +pub mod state; #[doc(hidden)] pub mod stores; pub mod sync; @@ -37,6 +41,7 @@ pub mod prelude { #[cfg(feature = "alloc")] pub use crate::errors::prelude::*; pub use crate::id::prelude::*; + pub use crate::state::prelude::*; #[doc(hidden)] pub use crate::stores::prelude::*; pub use crate::sync::prelude::*; diff --git a/actors/src/state/base_state.rs b/core/src/state/interface.rs similarity index 100% rename from actors/src/state/base_state.rs rename to core/src/state/interface.rs diff --git a/core/src/state/kinds.rs b/core/src/state/kinds.rs new file mode 100644 index 00000000..3cc3063b --- /dev/null +++ b/core/src/state/kinds.rs @@ -0,0 +1,34 @@ +/* + Appellation: binary + Contrib: FL03 +*/ +use super::State; + +/// A type alias for a [Nary] state with a default value of 4. +pub type NState = State, T>; + +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum Nary {} + +macro_rules! impl_state_kind { + (@kind $n:literal) => { + paste::paste! { + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] + pub enum [] {} + } + }; + (@state $name:ident($n:literal)) => { + paste::paste! { + pub type [<$name State>] = State<[], T>; + } + }; + ($($name:ident($n:literal)),* $(,)?) => { + $( + impl_state_kind!(@kind $n); + impl_state_kind!(@state $name($n)); + )* + }; +} + +impl_state_kind!(Unary(1), Binary(2), Ternary(3)); diff --git a/actors/src/state/mod.rs b/core/src/state/mod.rs similarity index 59% rename from actors/src/state/mod.rs rename to core/src/state/mod.rs index 73393b75..a914e7d6 100644 --- a/actors/src/state/mod.rs +++ b/core/src/state/mod.rs @@ -6,15 +6,15 @@ //! //! This module contains the stateful types and traits for the library. #[doc(inline)] -pub use self::{base_state::*, kinds::*}; +pub use self::{interface::State, kinds::*}; -mod base_state; +mod interface; mod kinds; -#[allow(unused_imports)] pub(crate) mod prelude { - pub use super::base_state::*; + pub use super::interface::*; pub use super::kinds::*; + pub use super::{RawState, Stateful}; } /// [Stateful] @@ -38,17 +38,3 @@ impl RawState for State { impl Stateful for State { type State = State; } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_nary_state() { - let state = NState::::new(0); - assert!(state.is_state::>()); - - assert!(!state.is_state::>()); - assert!(!state.is_state::>()); - } -} diff --git a/core/tests/state.rs b/core/tests/state.rs new file mode 100644 index 00000000..9c12a078 --- /dev/null +++ b/core/tests/state.rs @@ -0,0 +1,16 @@ +/* + Appellation: state + Contrib: FL03 +*/ +extern crate scsys_core as scsys; + +use scsys::state::*; + +#[test] +fn test_nary_state() { + let state = NState::::new(0); + assert!(state.is_state::>()); + + assert!(!state.is_state::>()); + assert!(!state.is_state::>()); +} \ No newline at end of file diff --git a/scsys/Cargo.toml b/scsys/Cargo.toml index 70496b15..9143547a 100644 --- a/scsys/Cargo.toml +++ b/scsys/Cargo.toml @@ -51,13 +51,19 @@ alloc = [ "scsys-actors?/alloc", "scsys-utils?/alloc", ] + +chrono = [ + "scsys-core/chrono", +] + rand = [ "scsys-core/rand", ] serde = [ - "scsys-actors?/serde", "scsys-core/serde", + "scsys-actors?/serde", + "scsys-utils?/serde", ] tokio = [ From a2b2c97af92f152ef3eed7c2f1241080cd9cf94d Mon Sep 17 00:00:00 2001 From: FL03 Date: Sun, 22 Sep 2024 12:23:28 -0500 Subject: [PATCH 17/18] update Signed-off-by: FL03 --- .gitignore | 59 +++++++++++++++++++++++++++++++++++++++++++++++++---- SECURITY.md | 2 +- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 68374cb2..b2d1ab38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,63 @@ +## Config +*.env +*.env.* +!.env.example + +## Development + +### JetBrains +**/.idea/ + +**/*.iml +### VisualStudio Code +**/.vscode/ + +## Languages + +### Node.js +**/.DS_Store/ + +**/build/ +**/node_modules/ + +**/npm-debug.log + +**/package-lock.json +**/pnpm-lock.* + +**/yarn-error.log +**/yarn-debug.log +**/yarn.lock + +### Python +**/__pycache__/ +**/.pytest_cache/ +**/env/ +**/venv/ + +**/*.pyc ### Rust **/target/ **/Cargo.lock -**/*.bk -**/*.bk-* +**/*.rs.bk +**/*.rs.bk-* + +*.log +*.log.* + +## Miscellaneous + +### Extensions + +*.log +*.log.* + +## Operating Systems + +### NixOs -**/log.* -**/*log.* +!**/flake.lock \ No newline at end of file diff --git a/SECURITY.md b/SECURITY.md index a5d6c84d..c28336d7 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,7 +12,7 @@ This section is used to update intrested parties as to which versions are curren ## Reporting a Vulnerability -If you discover a vulnerability feel free to email me at support@scattered-systems.com or visit the company [website](https://scsys.eth.limo) for more information. +If you discover a vulnerability feel free to email me at [support@scattered-systems.com] or visit the company [website](https://scsys.eth.limo) for more information. ### GitHub From d8954375d947d7302d45846aad0d46dcbc41ab42 Mon Sep 17 00:00:00 2001 From: FL03 Date: Sun, 22 Sep 2024 12:29:32 -0500 Subject: [PATCH 18/18] update Signed-off-by: FL03 --- .github/workflows/clippy.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 151a6ddb..cbd07f8a 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -20,26 +20,31 @@ permissions: jobs: clippy: - name: Clippy runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - name: setup (rust) + - + name: checkout + uses: actions/checkout@v4 + - + name: setup (rust) uses: actions-rs/toolchain@v1 with: profile: minimal toolchain: stable components: clippy override: true - - name: setup (clippy) + - + name: setup (clippy) run: cargo install clippy-sarif sarif-fmt - - name: analyze + - + name: analyze run: cargo clippy --all-features --message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt continue-on-error: true - - name: Upload analysis + - + name: Upload analysis uses: github/codeql-action/upload-sarif@v3 with: sarif_file: rust-clippy-results.sarif