From b3d6f91674155ee443a39fedca44790cd9e2ec02 Mon Sep 17 00:00:00 2001 From: Lukas Bergdoll Date: Sat, 11 Nov 2023 10:42:13 +0100 Subject: [PATCH] Minimize README --- README.md | 175 ------------------------------------------------------ 1 file changed, 175 deletions(-) diff --git a/README.md b/README.md index eeee9b1..5b9464c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,3 @@ -[github](https://github.com/Voultapher/self_cell) -[crates.io](https://crates.io/crates/self_cell) -[docs.rs](https://docs.rs/self_cell) - # Note on version 0.10.3 This version of `self_cell` is a re-export of the `self_cell` version `1` @@ -9,177 +5,6 @@ meant for backwards-compatibly allowing `0.10` users to get current and future soundness fixes. If you are adding `self_cell` as a dependency, please use an up-to-date version directly. -# `self_cell!` - -Use the macro-rules macro: `self_cell!` to create safe-to-use self-referential -structs in stable Rust, without leaking the struct internal lifetime. - -In a nutshell, the API looks *roughly* like this: - -```rust -// User code: - -self_cell!( - struct NewStructName { - owner: Owner, - - #[covariant] - dependent: Dependent, - } - - impl {Debug} -); - -// Generated by macro: - -struct NewStructName(...); - -impl NewStructName { - fn new( - owner: Owner, - dependent_builder: impl for<'a> FnOnce(&'a Owner) -> Dependent<'a> - ) -> NewStructName { ... } - fn borrow_owner<'a>(&'a self) -> &'a Owner { ... } - fn borrow_dependent<'a>(&'a self) -> &'a Dependent<'a> { ... } -} - -impl Debug for NewStructName { ... } -``` - -Self-referential structs are currently not supported with safe vanilla Rust. The -only reasonable safe alternative is to expect the user to juggle 2 separate data -structures which is a mess. The library solution ouroboros is really expensive -to compile due to its use of procedural macros. - -This alternative is `no_std`, uses no proc-macros, some self contained unsafe -and works on stable Rust, and is miri tested. With a total of less than 300 -lines of implementation code, which consists mostly of type and trait -implementations, this crate aims to be a good minimal solution to the problem of -self-referential structs. - -It has undergone [community code review](https://users.rust-lang.org/t/experimental-safe-to-use-proc-macro-free-self-referential-structs-in-stable-rust/52775) -from experienced Rust users. - -### Fast compile times - -``` -$ rm -rf target && cargo +nightly build -Z timings - -Compiling self_cell v0.9.0 -Completed self_cell v0.9.0 in 0.2s -``` - -Because it does **not** use proc-macros, and has 0 dependencies compile-times -are fast. - -Measurements done on a slow laptop. - -### A motivating use case - -```rust -use self_cell::self_cell; - -#[derive(Debug, Eq, PartialEq)] -struct Ast<'a>(pub Vec<&'a str>); - -self_cell!( - struct AstCell { - owner: String, - - #[covariant] - dependent: Ast, - } - - impl {Debug, Eq, PartialEq} -); - -fn build_ast_cell(code: &str) -> AstCell { - // Create owning String on stack. - let pre_processed_code = code.trim().to_string(); - - // Move String into AstCell, then build Ast inplace. - AstCell::new( - pre_processed_code, - |code| Ast(code.split(' ').filter(|word| word.len() > 1).collect()) - ) -} - -fn main() { - let ast_cell = build_ast_cell("fox = cat + dog"); - - println!("ast_cell -> {:?}", &ast_cell); - println!("ast_cell.borrow_owner() -> {:?}", ast_cell.borrow_owner()); - println!("ast_cell.borrow_dependent().0[1] -> {:?}", ast_cell.borrow_dependent().0[1]); -} -``` - -``` -$ cargo run - -ast_cell -> AstCell { owner: "fox = cat + dog", dependent: Ast(["fox", "cat", "dog"]) } -ast_cell.borrow_owner() -> "fox = cat + dog" -ast_cell.borrow_dependent().0[1] -> "cat" -``` - -There is no way in safe Rust to have an API like `build_ast_cell`, as soon as -`Ast` depends on stack variables like `pre_processed_code` you can't return the -value out of the function anymore. You could move the pre-processing into the -caller but that gets ugly quickly because you can't encapsulate things anymore. -Note this is a somewhat niche use case, self-referential structs should only be -used when there is no good alternative. - -Under the hood, it heap allocates a struct which it initializes first by moving -the owner value to it and then using the reference to this now Pin/Immovable -owner to construct the dependent inplace next to it. This makes it safe to move -the generated SelfCell but you have to pay for the heap allocation. - -See the documentation for a more in-depth API overview and advanced examples: -https://docs.rs/self_cell - -### Installing - -[See cargo docs](https://doc.rust-lang.org/cargo/guide/). - -## Running the tests - -``` -cargo test - -cargo miri test -``` - -### Related projects - -[ouroboros](https://github.com/joshua-maros/ouroboros) - -[rental](https://github.com/jpernst/rental) - -[Schroedinger](https://github.com/dureuill/sc) - -[owning_ref](https://github.com/Kimundi/owning-ref-rs) - -[ghost-cell](https://github.com/matthieu-m/ghost-cell) - -## Min required rustc version - -By default the minimum required rustc version is 1.51. - -There is an optional feature you can enable called "old_rust" that enables -support down to rustc version 1.36. However this requires polyfilling std -library functionality for older rustc with technically UB versions. Testing does -not show older rustc versions (ab)using this. Use at your own risk. - -The minimum versions are a best effor and may change with any new major release. - -## Contributing - -Please respect the [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) when contributing. - -## Versioning - -We use [SemVer](http://semver.org/) for versioning. For the versions available, -see the [tags on this repository](https://github.com/Voultapher/self_cell/tags). - ## Authors * **Lukas Bergdoll** - *Initial work* - [Voultapher](https://github.com/Voultapher)