diff --git a/README.md b/README.md index 04375c0..b2428bb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,43 @@ -# Digestible +# Digestible [![Build Status]][actions] [![Latest Version]][crates.io] +[Build Status]: https://img.shields.io/github/actions/workflow/status/wyatt-herkamp/digestible/commit.yml?branch=master +[actions]: https://github.com/wyatt-herkamp/digestible/actions?query=branch%3Amaster +[Latest Version]: https://img.shields.io/crates/v/digestible.svg +[crates.io]: https://crates.io/crates/digestible A more dynamic Hash and Hashable trait for Rust +--- -## Example +## Key Difference over STD Hash and Hashable +- ByteOrder is built in. So you can digest number types in any byte order. [ByteOrder](https://docs.rs/byteorder/latest/byteorder/) +- Output is a Generic Associated Type. + So you can Digest into a ByteArray, + String with [Base64](https://docs.rs/digestible/0.2.0/digestible/to_base64/index.html) + or any type the Digester uses. +- Skip Fields with `#[digestible(skip)]` +- 'digest_with' and 'with' to override the default digest behavior. [digest_with](https://docs.rs/digestible/0.2.0/digestible/digest_with/index.html) +- Support for all Hashing Algorithms that implement [digest::Digest](https://docs.rs/digest/latest/digest/) such as SHA2, md-5, and many more. +- Writing Type Headers to prevent collisions with similar types. (This is optional and can be disabled with `#[digestible(type_header = none)]`) +--- + +## Features +- No STD Support +- Digest to implement Digester for all types that implement [digest::Digest](https://docs.rs/digest/latest/digest/) +- Float and Atomic Support using `digest_with` + +--- +## Working with Hash +### For types that do not Implement Digestible +you can add `#[digestible(digest_with = digest_with_hash)]` to your variable +to tell Digestible to use Hash to digest it. + +### Implementing Hash with Digestible. +Adding `#[digestible(hash)]` to your struct or enum will implement Hash for it. +Using the digest function. +Allowing you to have a Hash and Digestible that are the same. + + + +## Example Using SHA2 ```rust #[derive(Digestible)] pub struct MyStruct { @@ -18,7 +53,7 @@ fn digest_to_bytes(){ password: "Test".to_string(), }; let mut hasher = sha2::Sha256::new(); - let result = hasher.digest(&test); // This will be the type of sha2 Output + let result = hasher.digest_native(&test); // This will be the type of sha2 Output } fn digest_to_base64(){ let test = MyStruct{ @@ -27,15 +62,6 @@ fn digest_to_base64(){ password: "Test".to_string(), }; let hasher = sha2::Sha256::new().into_base64(); - let result = hasher.digest(&test); // This is a base64 encoded string + let result = hasher.digest_native(&test); // This is a base64 encoded string } -``` -Then you can select any hasher that implements Digester. -When you enable the `digest` feature all hashes that implement [digezst::Digest](https://docs.rs/digest/latest/digest/) such as SHA2 will be available. - -## Key Difference. -- ByteOrder is built in. So you can digest number types in any byte order. -- Output is a Generic Associated Type. - So you can Digest into a ByteArray, String with [Base64](https://docs.rs/digestible/0.2.0-rc.1/digestible/struct.ToBase64.html) - or any other that the Digester implements. -- Atomic Support Via [Digest With](https://docs.rs/digestible/0.2.0-rc.1/digestible/derive.Digestible.html#digest-with-example) and the [provided functions](https://docs.rs/digestible/0.2.0-rc.1/digestible/digest_with/atomics/index.html) \ No newline at end of file +``` \ No newline at end of file diff --git a/digestible/Cargo.toml b/digestible/Cargo.toml index 7bffabd..dd0bbcf 100644 --- a/digestible/Cargo.toml +++ b/digestible/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "digestible" -version = "0.2.0-rc.2" +version = "0.2.0" edition = "2021" authors = ["Wyatt Herkamp "] description = "A more dynamic Hash and Hasher interface" @@ -16,7 +16,7 @@ rust-version="1.70" [dependencies] digest_0_10 = {package = "digest", version = "0.10", optional = true } byteorder = "1" -digestible-macros= {path="../macros",optional = true, version = "0.2.0-rc.2" } +digestible-macros= {path="../macros",optional = true, version = "0.2.0" } base64 = { version = "0.21", optional = true } bytes = { version = "1" , optional = true} [dev-dependencies] @@ -24,7 +24,6 @@ sha2 = "0.10" base64 = "0.21" digestible-macros= {path="../macros"} digestible = { path = ".", features = ["base64"] } -chrono = "0.4" [features] default = ["digest_0_10","derive", "std", "alloc"] derive = ["digestible-macros"] diff --git a/digestible/src/digestible/mod.rs b/digestible/src/digestible/mod.rs index fbc7b7b..75f49d0 100644 --- a/digestible/src/digestible/mod.rs +++ b/digestible/src/digestible/mod.rs @@ -14,10 +14,11 @@ So if you decide to write floats you should be aware of this. Maybe you should try rounding the floats to a certain precision before writing them. Or even better round them to an integer. +You can use [digest_with](crate::digest_with::floats) to do this. ## rc::Weak and sync::Weak These will attempt an upgrade and then call the digest method on the result. -This will just digest the [Option] if the upgrade fails. +This will just digest the [Option](Option) that is returned. ## Option and Result These follow the same pattern as the STD library. diff --git a/digestible/src/to_base64.rs b/digestible/src/to_base64.rs index 5e00534..973c932 100644 --- a/digestible/src/to_base64.rs +++ b/digestible/src/to_base64.rs @@ -71,4 +71,5 @@ where fn digest(self, data: &impl Digestible) -> Self::Target { Self::encode_base64(self.0.digest::(data)) } + } diff --git a/digestible/tests/test.rs b/digestible/tests/test.rs index d31c2bd..4d36cd2 100644 --- a/digestible/tests/test.rs +++ b/digestible/tests/test.rs @@ -1,7 +1,6 @@ use base64::engine::general_purpose::STANDARD; use base64::Engine; use byteorder::{ByteOrder, NativeEndian}; -use chrono::NaiveDateTime; use digestible::digester::Digester; use digestible::to_base64::IntoBase64; use digestible::DigestWriter; @@ -57,22 +56,10 @@ pub fn test_base64() { #[derive(Digestible)] pub struct TupleStruct(String); #[derive(Digestible)] -pub struct CommonSimilarButDifferent { - pub active: bool, - #[digestible(digest_with = digest_with_hash)] - pub created: NaiveDateTime, -} -#[derive(Digestible)] -pub struct SimilarButDifferentOne { - pub id: u32, - pub username: String, - pub common: CommonSimilarButDifferent, -} -#[derive(Digestible)] -pub struct SimilarButDifferentTwo { - pub id: u32, +#[digestible(hash = LittleEndian, type_header = None)] +pub struct NoHeader{ pub name: String, - pub common: CommonSimilarButDifferent, + pub id: u32, } #[derive(Digestible)] #[digestible(hash = LittleEndian)] diff --git a/macros/Cargo.toml b/macros/Cargo.toml index cb93135..3b560b7 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "digestible-macros" -version = "0.2.0-rc.2" +version = "0.2.0" edition = "2021" authors = ["Wyatt Herkamp "] description = "Macros for generating digest implementations" diff --git a/macros/src/container_attrs.rs b/macros/src/container_attrs.rs index cb69839..7f1ee55 100644 --- a/macros/src/container_attrs.rs +++ b/macros/src/container_attrs.rs @@ -50,6 +50,9 @@ impl Parse for ContainerAttrs { let mut type_header = TypeHeader::default(); let mut impl_hash = None; while !input.is_empty() { + if input.peek(syn::Token![,]) { + let _: syn::Token![,] = input.parse()?; + } let lookahead = input.lookahead1(); if lookahead.peek(keywords::type_header) { let _ = input.parse::()?;