diff --git a/CHANGELOG.md b/CHANGELOG.md index 501136c6b..1714fa916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,18 +3,19 @@ ![Image of the kibō Web App version 0.X.Y](https://github.com/kibo-money/kibo/blob/main/_assets/v0.X.Y.jpg) --> -# v0.6.0 | WIP +# v0.6.0 | WIP | A new beginning ## Global +- Completely redesign the back-end + - Merged parser and server crates into a single project (and thus executable), so now both will run at the same time with a single `cargo run -r` [#7392982](https://github.com/kibo-money/kibo/commit/7392982824c2db94bcd57251fd41986117c29a23) - Added `--no-server` and `--no-parser` to disable each if needed - Improved executable parameters - Started using `log` and `env_logger` crates instead of custom code [#7392982](https://github.com/kibo-money/kibo/commit/7392982824c2db94bcd57251fd41986117c29a23) - Improved logs -- Automated databases defragmention (and removed parameter) to improve disk usage and parse speed [#7392982](https://github.com/kibo-money/kibo/commit/7392982824c2db94bcd57251fd41986117c29a23) - Fixed input being unfocused right after being focused in Brave browser [#9a9ae61](https://github.com/kibo-money/kibo/commit/9a9ae614d07b54c08b7e9c0e2aefe3b52fdb93c5) -- Moved Sanakirja database wrapper to its own crate: `snkrj` [0f936dc](https://github.com/kibo-money/kibo/commit/0f936dcdfbecac0a228f023bd500d6e98f56446a) + - Reworked server's API code [#6ab0f46]( https://github.com/kibo-money/kibo/commit/6ab0f463119a902a1b7ca9691b54f61543bb8f2f) - New route format: `/api/date-to-realized-price` is now `/api/realized-price?kind=date` - Added status and timing to logs @@ -25,12 +26,16 @@ - Created separate crate for indexing called `bindex` - Created a crate a storage engine specialized in storing datasets that have indexes as keys and thus can be represented by an array/vec called `storable-vec` - Removed the need for the `-txindex=1` parameter when starting your Bitcoin Core node as kibō has its own indexes now -- `snkrj` added a robust auto defragmentation to improve disk usage without the need for user's intervention ## Git Added git tags for each version though Markdown won't display formatted on Github so left the default text +## Deprecated + +Moved Sanakirja database wrapper to its own crate (`snkrj`) and added a robust auto defragmentation to improve disk usage without the need for user's intervention. +Since it's not used anymore it will moved out of the repository relatively soon. + # [v0.5.0](https://github.com/kibo-money/kibo/tree/eea56d394bf92c62c81da8b78b8c47ea730683f5) | [873199](https://mempool.space/block/0000000000000000000270925aa6a565be92e13164565a3f7994ca1966e48050) - 2024/12/04 ![Image of the kibō Web App version 0.5.0](https://github.com/kibo-money/kibo/blob/main/_assets/v0.5.0.jpg) diff --git a/Cargo.lock b/Cargo.lock index 45be29409..3270679e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,7 +267,6 @@ dependencies = [ "serde", "serde_json", "storable_vec", - "struct_iterable", "tokio", "tower-http", "zstd", @@ -751,7 +750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -786,9 +785,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "fjall" -version = "2.6.2" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ddab3925ea1ed59863d246305c7bc113dc2e12b691405d2d02e429cfa0c87a5" +checksum = "c240d783ba894f1ce20a7337c4eabb7814920b4bfd1ae74da1b17af3c7dfc19a" dependencies = [ "byteorder", "byteview", @@ -808,7 +807,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", - "miniz_oxide 0.8.3", + "miniz_oxide 0.8.4", ] [[package]] @@ -1302,7 +1301,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1403,9 +1402,9 @@ dependencies = [ [[package]] name = "lsm-tree" -version = "2.6.2" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2880324e429cd3285e56d0382c025b3d9336d672bbf344e3fde9783a5623f0f6" +checksum = "43b7d9dc8488e02ab7be88626cdbd3a6ee4690d7ffa6a2ad460da9e52105e393" dependencies = [ "byteorder", "crossbeam-skiplist", @@ -1469,9 +1468,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" +checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b" dependencies = [ "adler2", ] @@ -1906,9 +1905,9 @@ dependencies = [ [[package]] name = "oxc_sourcemap" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48557f779d04c8bfa8a930db5a3c35c0a86ff4e6bf1552ce446b9596a6e77c42" +checksum = "989c3fa8bdd55ced0ad4a0b2d587dfd11613364c9db417889bdb09c217463766" dependencies = [ "base64-simd", "cfg-if", @@ -2111,6 +2110,10 @@ dependencies = [ "zerocopy 0.7.35", ] +[[package]] +name = "pricer" +version = "0.1.0" + [[package]] name = "proc-macro2" version = "1.0.93" @@ -2334,14 +2337,14 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.22" +version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ "once_cell", "rustls-pki-types", @@ -2633,26 +2636,6 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6" -[[package]] -name = "struct_iterable" -version = "0.1.2" -dependencies = [ - "struct_iterable_derive", - "struct_iterable_internal", -] - -[[package]] -name = "struct_iterable_derive" -version = "0.1.0" -dependencies = [ - "quote", - "syn 2.0.98", -] - -[[package]] -name = "struct_iterable_internal" -version = "0.1.1" - [[package]] name = "subtle" version = "2.6.1" @@ -2733,7 +2716,7 @@ dependencies = [ "getrandom 0.3.1", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3017,9 +3000,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-log" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5589fb4f51f528b0cca7fdd03ec63a67f447bdcd313b09cdf9d2fc519149c02a" +checksum = "cdbb3c254a6def3cbc8afcb523b88c4a3b424297db8207aa66cde5fa84edddf6" dependencies = [ "byteorder", "byteview", diff --git a/Cargo.toml b/Cargo.toml index 5c77d7399..a4a4a6eb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,9 +5,9 @@ members = [ "indexer", "iterator", "logger", + "pricer", "server", "storable_vec", - "struct_iterable", ] resolver = "2" @@ -17,7 +17,7 @@ color-eyre = "0.6.3" computer = { path = "computer", package = "bomputer" } derive_deref = "1.1.1" exit = { path = "exit" } -fjall = "2.6.2" +fjall = "2.6.3" indexer = { path = "indexer", package = "bindex" } iterator = { path = "iterator", package = "biter" } jiff = "0.2.0" @@ -27,5 +27,4 @@ rlimit = { version = "0.10.2" } serde = { version = "1.0.217", features = ["derive"] } server = { path = "server", package = "berver" } storable_vec = { path = "storable_vec" } -struct_iterable = { path = "struct_iterable" } zerocopy = { version = "0.8.17", features = ["derive"] } diff --git a/computer/src/structs/dateindex.rs b/computer/src/structs/dateindex.rs new file mode 100644 index 000000000..e69de29bb diff --git a/pricer/Cargo.toml b/pricer/Cargo.toml new file mode 100644 index 000000000..c2ba1eb70 --- /dev/null +++ b/pricer/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "pricer" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/pricer/src/lib.rs b/pricer/src/lib.rs new file mode 100644 index 000000000..b93cf3ffd --- /dev/null +++ b/pricer/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/server/Cargo.toml b/server/Cargo.toml index 0fe82bc21..e402111b2 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -28,7 +28,6 @@ reqwest = { version = "0.12.12", features = ["blocking", "json"] } serde = { workspace = true } serde_json = { version = "1.0.138", features = ["float_roundtrip"] } storable_vec = { workspace = true } -struct_iterable = { workspace = true } tokio = { version = "1.43.0", features = ["full"] } tower-http = { version = "0.6.2", features = ["compression-full"] } zstd = "0.13.2" diff --git a/server/src/api/handlers/last_values.rs b/server/src/api/handlers/last_values.rs deleted file mode 100644 index 1ba426f0a..000000000 --- a/server/src/api/handlers/last_values.rs +++ /dev/null @@ -1,13 +0,0 @@ -use axum::{ - extract::State, - response::{IntoResponse, Response}, -}; -use serde_json::Value; - -use crate::{io::Json, server::AppState}; - -pub async fn last_values_handler(State(app_state): State) -> Response { - let values = Json::import::(&app_state.config.path_datasets_last_values()).unwrap(); - let values = axum::Json(values); - values.into_response() -} diff --git a/server/src/api/structs/index.rs b/server/src/api/structs/index.rs index 5de782cdf..a8025a659 100644 --- a/server/src/api/structs/index.rs +++ b/server/src/api/structs/index.rs @@ -1,6 +1,6 @@ use std::fmt::{self, Debug}; -use computer::Date; +use computer::Dateindex; use indexer::{ Addressindex, Height, P2PK33index, P2PK65index, P2PKHindex, P2SHindex, P2TRindex, P2WPKHindex, P2WSHindex, Txindex, Txinindex, Txoutindex, @@ -9,7 +9,7 @@ use indexer::{ #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum Index { Addressindex, - Date, + DateIndex, Height, P2PK33index, P2PK65index, @@ -27,19 +27,19 @@ impl TryFrom<&str> for Index { type Error = (); fn try_from(value: &str) -> Result { Ok(match value { - "addri" | "addressindex" => Self::Addressindex, "d" | "date" => Self::Date, "h" | "height" => Self::Height, - "p2pk33index" => Self::P2PK33index, - "p2pk65index" => Self::P2PK65index, - "p2pkhindex" => Self::P2PKHindex, - "p2shindex" => Self::P2SHindex, - "p2trindex" => Self::P2TRindex, - "p2wpkhindex" => Self::P2WPKHindex, - "p2wshindex" => Self::P2WSHindex, "txi" | "txindex" => Self::Txindex, "txini" | "txinindex" => Self::Txinindex, "txouti" | "txoutindex" => Self::Txoutindex, + "addri" | "addressindex" => Self::Addressindex, + "p2pk33i" | "p2pk33index" => Self::P2PK33index, + "p2pk65i" | "p2pk65index" => Self::P2PK65index, + "p2pkhi" | "p2pkhindex" => Self::P2PKHindex, + "p2shi" | "p2shindex" => Self::P2SHindex, + "p2tri" | "p2trindex" => Self::P2TRindex, + "p2wpkhi" | "p2wpkhindex" => Self::P2WPKHindex, + "p2wshi" | "p2wshindex" => Self::P2WSHindex, _ => return Err(()), }) } @@ -60,9 +60,9 @@ impl IndexTypeToIndexEnum for Addressindex { Index::Addressindex } } -impl IndexTypeToIndexEnum for Date { +impl IndexTypeToIndexEnum for Dateindex { fn to_enum() -> Index { - Index::Date + Index::DateIndex } } impl IndexTypeToIndexEnum for Height { diff --git a/server/src/api/structs/range.rs b/server/src/api/structs/range.rs deleted file mode 100644 index 84754a07e..000000000 --- a/server/src/api/structs/range.rs +++ /dev/null @@ -1,32 +0,0 @@ -use axum::extract::Query; -use color_eyre::eyre::eyre; - -use crate::server::api::handlers::DatasetParams; - -pub enum DatasetRange { - All, - Chunk(DatasetRangeChunk), -} - -impl TryFrom<&Query> for DatasetRange { - type Error = color_eyre::Report; - - fn try_from(query: &Query) -> Result { - if let Some(chunk) = query.chunk { - if query.all.is_some() { - Err(eyre!("chunk and all are exclusive")) - } else { - Ok(Self::Chunk(DatasetRangeChunk::Chunk(chunk))) - } - } else if query.all.is_some() { - Ok(Self::All) - } else { - Ok(Self::Chunk(DatasetRangeChunk::Last)) - } - } -} - -pub enum DatasetRangeChunk { - Chunk(usize), - Last, -} diff --git a/struct_iterable/Cargo.lock b/struct_iterable/Cargo.lock deleted file mode 100644 index 582ac585d..000000000 --- a/struct_iterable/Cargo.lock +++ /dev/null @@ -1,60 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "proc-macro2" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "struct_iterable" -version = "0.1.2" -dependencies = [ - "struct_iterable_derive", - "struct_iterable_internal", -] - -[[package]] -name = "struct_iterable_derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "struct_iterable_internal", - "syn", -] - -[[package]] -name = "struct_iterable_internal" -version = "0.1.1" - -[[package]] -name = "syn" -version = "2.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" diff --git a/struct_iterable/Cargo.toml b/struct_iterable/Cargo.toml deleted file mode 100644 index ba00c67ad..000000000 --- a/struct_iterable/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -name = "struct_iterable" -version = "0.1.2" -authors = ["André de Moraes "] -edition = "2021" -description = "A Rust library providing a proc macro to make a struct iterable." -license = "MIT" -repository = "https://github.com/decomoraes/rust_struct_iterable" -readme = "README.md" -keywords = ["proc-macro", "struct", "iterable"] -categories = ["development-tools::cargo-plugins"] -homepage = "https://github.com/decomoraes/rust_struct_iterable" -documentation = "https://docs.rs/struct_iterable" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -struct_iterable_derive = { path = "./struct_iterable_derive" } -struct_iterable_internal = { path = "./struct_iterable_internal" } - -[lib] -name = "struct_iterable" -path = "src/lib.rs" - -[package.metadata.docs.rs] -all-features = true diff --git a/struct_iterable/README.md b/struct_iterable/README.md deleted file mode 100644 index b7cecc86a..000000000 --- a/struct_iterable/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# Struct Iterable - -`Struct Iterable` is a Rust library that provides a proc macro to make a struct iterable. This allows you to iterate over the fields of your struct in a generic way, with each iteration returning a tuple containing the name of the field as a static string and a reference to the field's value as a `dyn Any`. - -## How to Use - -First, add `Struct Iterable` to your `Cargo.toml`: - -```toml -[dependencies] -struct_iterable = "0.1.1" -``` - -Next, include the library at the top of your Rust file: - -```rust -use struct_iterable::Iterable; -``` - -Finally, add the `#[derive(Iterable)]` attribute to your struct: - -```rust -#[derive(Iterable)] -struct MyStruct { - field1: u32, - field2: String, - // etc. -} -``` - -Now, you can iterate over the fields of an instance of your struct: - -```rust -let my_instance = MyStruct { - field1: 42, - field2: "Hello, world!".to_string(), -}; - -for (field_name, field_value) in my_instance.iter() { - println!("{}: {:?}", field_name, field_value); -} -``` - -## Limitations -- Only structs with named fields are supported. -- Only structs are supported, not enums or unions. - -## Implementation - -Here is the implementation of the proc macro: - -```rust -extern crate proc_macro; - -use proc_macro::TokenStream; -use quote::quote; -use syn::{parse_macro_input, Data, DeriveInput, Fields}; -use iterable_structs::Iterable; - -#[proc_macro_derive(Iterable)] -pub fn derive_iterable(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let struct_name = input.ident; - let fields = match input.data { - Data::Struct(data_struct) => match data_struct.fields { - Fields::Named(fields_named) => fields_named.named, - _ => panic!("Only structs with named fields are supported"), - }, - _ => panic!("Only structs are supported"), - }; - - let fields_iter = fields.iter().map(|field| { - let field_ident = &field.ident; - let field_name = field_ident.as_ref().unwrap().to_string(); - quote! { - (#field_name, &(self.#field_ident) as &dyn std::any::Any) - } - }); - - let expanded = quote! { - impl Iterable for #struct_name { - fn iter<'a>(&'a self) -> std::vec::IntoIter<(&'static str, &'a dyn std::any::Any)> { - vec![ - #(#fields_iter),* - ].into_iter() - } - } - }; - - TokenStream::from(expanded) -} -``` - -The macro takes in the TokenStream of a struct and expands it into an implementation of the Iterable trait for that struct. This trait provides an iter method that returns an iterator over tuples of field names and values. - -## Contributing and License - -`Struct Iterable` is an open-source project, and contributions are warmly welcomed. Whether you're fixing bugs, improving the documentation, or proposing new features, your efforts are highly appreciated! - -If you're interested in contributing, please feel free to submit a pull request. For major changes, please open an issue first to discuss what you would like to change. - -Please note that this project is released with a Contributor Code of Conduct. By participating in this project, you agree to abide by its terms. - -`Struct Iterable` is distributed under the terms of the MIT license. As such, you're free to use, modify, distribute, and privately use it in any way you see fit, in accordance with the terms of the license. diff --git a/struct_iterable/src/lib.rs b/struct_iterable/src/lib.rs deleted file mode 100644 index c1fb55ed6..000000000 --- a/struct_iterable/src/lib.rs +++ /dev/null @@ -1,91 +0,0 @@ -/// The `Iterable` proc macro. -/// -/// This macro provides a convenient way to make a struct iterable. -/// The struct fields' names are returned as static strings and their values as `dyn Any`. -/// This allows to iterate over the struct fields in a generic way. -/// -/// Note that only structs with named fields are supported. -/// -/// # Example -/// -/// ``` -/// use struct_iterable::Iterable; -/// -/// #[derive(Iterable)] -/// struct MyStruct { -/// field1: i32, -/// field2: String, -/// // etc. -/// } -/// -/// let my_instance = MyStruct { -/// field1: 42, -/// field2: "Hello, world!".to_string(), -/// }; -/// -/// for (field_name, field_value) in my_instance.iter() { -/// println!("{}: {:?}", field_name, field_value); -/// } -/// ``` -pub use struct_iterable_derive::Iterable; - -/// The `Iterable` trait. -/// -/// This trait is implemented by the struct once the `Iterable` proc macro is derived. -/// It provides an `iter` method that returns an iterator over tuples of field names and values. -/// -/// # Example -/// -/// ``` -/// use struct_iterable::Iterable; -/// -/// #[derive(Iterable)] -/// struct MyStruct { -/// field1: i32, -/// field2: String, -/// // etc. -/// } -/// -/// let my_instance = MyStruct { -/// field1: 42, -/// field2: "Hello, world!".to_string(), -/// }; -/// -/// for (field_name, field_value) in my_instance.iter() { -/// println!("{}: {:?}", field_name, field_value); -/// } -/// ``` -pub use struct_iterable_internal::Iterable; - -#[cfg(test)] -mod tests { - use super::*; - - #[derive(Iterable)] - struct MyStruct { - field1: i32, - field2: String, - // etc. - } - - #[test] - fn it_works() { - let mut my_instance = MyStruct { - field1: 42, - field2: "Hello, world!".to_string(), - }; - - for (field_name, field_value) in my_instance.iter() { - dbg!("{}: {:?}", field_name, field_value); - } - - for (field_name, field_value) in my_instance.iter_mut() { - dbg!("{}: {:?}", field_name, &field_value); - if let Some(i32) = field_value.downcast_mut::() { - *i32 += 1; - dbg!(i32); - } - dbg!("{}: {:?}", field_name, &field_value); - } - } -} diff --git a/struct_iterable/struct_iterable_derive/Cargo.toml b/struct_iterable/struct_iterable_derive/Cargo.toml deleted file mode 100644 index a48babad4..000000000 --- a/struct_iterable/struct_iterable_derive/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "struct_iterable_derive" -version = "0.1.0" -authors = ["André de Moraes "] -edition = "2021" -description = "An internal crate for struct_iterable" -license = "MIT" - -[lib] -proc-macro = true -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -syn = "2.0.98" -quote = "1.0.38" diff --git a/struct_iterable/struct_iterable_derive/README.md b/struct_iterable/struct_iterable_derive/README.md deleted file mode 100644 index 5703ba278..000000000 --- a/struct_iterable/struct_iterable_derive/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Struct Iterable Derive - -This crate is a supporting library for the `struct_iterable` crate. It provides the proc macro `Iterable` which is used in conjunction with the `struct_iterable_internal` crate to provide an easy way to make a struct iterable in Rust. - -**Please note:** This crate is not intended to be used directly. If you want to make your structs iterable, please use the `struct_iterable` crate instead. - -Please visit the [`struct_iterable` crate on crates.io](https://crates.io/crates/struct_iterable) for more information and usage examples. diff --git a/struct_iterable/struct_iterable_derive/src/lib.rs b/struct_iterable/struct_iterable_derive/src/lib.rs deleted file mode 100644 index db2a7a01c..000000000 --- a/struct_iterable/struct_iterable_derive/src/lib.rs +++ /dev/null @@ -1,88 +0,0 @@ -extern crate proc_macro; - -use proc_macro::TokenStream; -use quote::quote; -use syn::{parse_macro_input, Data, DeriveInput, Fields}; - -/// The `Iterable` proc macro. -/// -/// Deriving this macro for your struct will make it "iterable". An iterable struct allows you to iterate over its fields, returning a tuple containing the field name as a static string and a reference to the field's value as `dyn Any`. -/// -/// # Limitations -/// -/// - Only structs are supported, not enums or unions. -/// - Only structs with named fields are supported. -/// -/// # Usage -/// -/// Add the derive attribute (`#[derive(Iterable)]`) above your struct definition. -/// -/// ``` -/// use struct_iterable::Iterable; -/// -/// #[derive(Iterable)] -/// struct MyStruct { -/// field1: i32, -/// field2: String, -/// } -/// ``` -/// -/// You can now call the `iter` method on instances of your struct to get an iterator over its fields: -/// -/// ``` -/// let my_instance = MyStruct { -/// field1: 42, -/// field2: "Hello, world!".to_string(), -/// }; -/// -/// for (field_name, field_value) in my_instance.iter() { -/// println!("{}: {:?}", field_name, field_value); -/// } -/// ``` -#[proc_macro_derive(Iterable)] -pub fn derive_iterable(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let struct_name = input.ident; - let fields = match input.data { - Data::Struct(data_struct) => match data_struct.fields { - Fields::Named(fields_named) => fields_named.named, - _ => panic!("Only structs with named fields are supported"), - }, - _ => panic!("Only structs are supported"), - }; - - let fields_iter = fields.iter().map(|field| { - let field_ident = &field.ident; - let field_name = field_ident.as_ref().unwrap().to_string(); - quote! { - (#field_name, &(self.#field_ident) as &dyn std::any::Any) - } - }); - - let fields_iter_mut = fields.iter().map(|field| { - let field_ident = &field.ident; - let field_name = field_ident.as_ref().unwrap().to_string(); - quote! { - (#field_name, &mut (self.#field_ident) as &mut dyn std::any::Any) - } - }); - - let expanded = quote! { - impl Iterable for #struct_name { - fn iter<'a>(&'a self) -> std::vec::IntoIter<(&'static str, &'a dyn std::any::Any)> { - vec![ - #(#fields_iter),* - ].into_iter() - } - - fn iter_mut<'a>(&'a mut self) -> std::vec::IntoIter<(&'static str, &'a mut dyn std::any::Any)> { - vec![ - #(#fields_iter_mut),* - ].into_iter() - } - } - }; - - TokenStream::from(expanded) -} diff --git a/struct_iterable/struct_iterable_internal/Cargo.toml b/struct_iterable/struct_iterable_internal/Cargo.toml deleted file mode 100644 index cdf06702c..000000000 --- a/struct_iterable/struct_iterable_internal/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "struct_iterable_internal" -version = "0.1.1" -authors = ["André de Moraes "] -edition = "2021" -description = "An internal crate for struct_iterable" -license = "MIT" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/struct_iterable/struct_iterable_internal/README.md b/struct_iterable/struct_iterable_internal/README.md deleted file mode 100644 index 462811fe4..000000000 --- a/struct_iterable/struct_iterable_internal/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Struct Iterable Internal - -This crate is a supporting library for the `struct_iterable` crate. It provides the `Iterable` trait which is used in conjunction with the `struct_iterable_derive` crate to provide an easy way to make a struct iterable in Rust. - -**Please note:** This crate is not intended to be used directly. If you want to make your structs iterable, please use the `struct_iterable` crate instead. - -Please visit the [`struct_iterable` crate on crates.io](https://crates.io/crates/struct_iterable) for more information and usage examples. diff --git a/struct_iterable/struct_iterable_internal/src/lib.rs b/struct_iterable/struct_iterable_internal/src/lib.rs deleted file mode 100644 index 1b5c7bb1c..000000000 --- a/struct_iterable/struct_iterable_internal/src/lib.rs +++ /dev/null @@ -1,58 +0,0 @@ -/// The `Iterable` trait. -/// -/// This trait is implemented for structs that derive the `Iterable` proc macro. -/// It provides the `iter` method which returns an iterator over the struct's fields as tuples, containing the field name as a static string and a reference to the field's value as `dyn Any`. -/// -/// You usually don't need to implement this trait manually, as it is automatically derived when using the `#[derive(Iterable)]` proc macro. -/// -/// # Example -/// -/// ``` -/// use struct_iterable::Iterable; -/// -/// #[derive(Iterable)] -/// struct MyStruct { -/// field1: i32, -/// field2: String, -/// } -/// -/// let my_instance = MyStruct { -/// field1: 42, -/// field2: "Hello, world!".to_string(), -/// }; -/// -/// // Iterate over the fields of `my_instance`: -/// for (field_name, field_value) in my_instance.iter() { -/// println!("{}: {:?}", field_name, field_value); -/// } -/// ``` -pub trait Iterable { - /// Returns an iterator over the struct's fields as tuples. - /// - /// Each tuple contains a field's name as a static string and a reference to the field's value as `dyn Any`. - /// - /// # Example - /// - /// ``` - /// use struct_iterable::Iterable; - /// - /// #[derive(Iterable)] - /// struct MyStruct { - /// field1: i32, - /// field2: String, - /// } - /// - /// let my_instance = MyStruct { - /// field1: 42, - /// field2: "Hello, world!".to_string(), - /// }; - /// - /// // Iterate over the fields of `my_instance`: - /// for (field_name, field_value) in my_instance.iter() { - /// println!("{}: {:?}", field_name, field_value); - /// } - /// ``` - fn iter(&self) -> std::vec::IntoIter<(&'static str, &'_ dyn std::any::Any)>; - - fn iter_mut(&mut self) -> std::vec::IntoIter<(&'static str, &'_ mut dyn std::any::Any)>; -}