diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml new file mode 100644 index 0000000..4907af8 --- /dev/null +++ b/.github/workflows/readme.yml @@ -0,0 +1,24 @@ +name: Check README + +on: + pull_request: + branches: [ "*" ] + +env: + CARGO_TERM_COLOR: always + CARGO_NET_GIT_FETCH_WITH_CLI: true + +jobs: + check_readme: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install cargo-hakari + uses: baptiste0928/cargo-install@v1 + with: + crate: cargo-readme + - name: Check that readme matches lib.rs + run: | + cp README.md README-copy.md + make readme + diff README.md README-copy.md \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aa16b78 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +readme: + cargo readme -i src/lib.rs -r udigest/ -t ../docs/readme.tpl \ + | perl -ne 's/\[(.+?)\]\(.+?\)/\1/g; print;' \ + | perl -ne 's/(? README.md diff --git a/README.md b/README.md index e69de29..21879a6 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,46 @@ +## Unambiguously digest structured data + +`udigest` provides utilities for unambiguous hashing the structured data. Structured +data can be anything that implements `Digestable` trait: + +* `str`, `String`, `CStr`, `CString` +* Integers: + `i8`, `i16`, `i32`, `i64`, `i128`, + `u8`, `u16`, `u32`, `u64`, `u128`, + `char` +* Containers: `Box`, `Arc`, `Rc`, `Cow`, `Option`, `Result` +* Collections: arrays, slices, `Vec`, `LinkedList`, `VecDeque`, `BTreeSet`, `BTreeMap` + +The trait is intentionally not implemented for certain types: + +* `HashMap`, `HashSet` as they can not be traversed in determenistic order +* `usize`, `isize` as their byte size varies on differnet platforms + +The `Digestable` trait can be implemented for the struct using a macro: +```rust +use udigest::{Tag, udigest}; +use sha2::Sha256; + +#[derive(udigest::Digestable)] +struct Person { + name: String, + job_title: String, +} +let alice = &Person { + name: "Alice".into(), + job_title: "cryptographer".into(), +}; + +let tag = Tag::::new("udigest.example"); +let hash = udigest(tag, &alice); +``` + +The crate intentionally does not try to follow any existing standards for unambiguous +encoding. The format for encoding was desingned specifically for `udigest` to provide +a better usage experience in Rust. The details of encoding format can be found in +`encoding` module. + +### Features +* `std` implements `Digestable` trait for types in standard library +* `alloc` implements `Digestable` trait for type in `alloc` crate +* `derive` enables `Digestable` proc macro diff --git a/docs/readme.tpl b/docs/readme.tpl new file mode 100644 index 0000000..274bb44 --- /dev/null +++ b/docs/readme.tpl @@ -0,0 +1 @@ +{{readme}} diff --git a/udigest/src/lib.rs b/udigest/src/lib.rs index 9a6b46b..93fcec1 100644 --- a/udigest/src/lib.rs +++ b/udigest/src/lib.rs @@ -1,4 +1,4 @@ -//! Unambiguously digest structured data +//! # Unambiguously digest structured data //! //! `udigest` provides utilities for unambiguous hashing the structured data. Structured //! data can be anything that implements [`Digestable`] trait: @@ -37,8 +37,13 @@ //! //! The crate intentionally does not try to follow any existing standards for unambiguous //! encoding. The format for encoding was desingned specifically for `udigest` to provide -//! a better usage experience in Rust. The details of encoding format can be found -//! [here](encoding). +//! a better usage experience in Rust. The details of encoding format can be found in +//! [`encoding` module](encoding). +//! +//! ## Features +//! * `std` implements `Digestable` trait for types in standard library +//! * `alloc` implements `Digestable` trait for type in `alloc` crate +//! * `derive` enables `Digestable` proc macro #![no_std] #![forbid(missing_docs)]