-
-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add clarifications for documentation #28
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
8673079
Add clarifications for documentation
kirillsemyonkin 9409776
Update README using cargo-rdme
kirillsemyonkin 08c48a1
Replace `&'static str` impl with `&T`
kirillsemyonkin 843c8b0
Add tests for simple types
kirillsemyonkin 9c4d86d
Fix README as suggested in a PR review
kirillsemyonkin 14cc9ff
Sync lib.rs and README for cargo-rdme
kirillsemyonkin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,25 +7,33 @@ | |
#![cfg_attr(docsrs, feature(doc_cfg))] | ||
//! # ImplicitClone | ||
//! | ||
//! A library that introduces the marker trait [`ImplicitClone`](crate::ImplicitClone) which allows | ||
//! reproducing the behavior of the trait [`Copy`][std::marker::Copy] but calls the | ||
//! [`Clone`][std::clone::Clone] implementation instead and must be implemented in the host | ||
//! library. | ||
//! This library introduces the marker trait [`ImplicitClone`](crate::ImplicitClone) intended for | ||
//! cheap-to-clone types that should be allowed to be cloned implicitly. It enables host libraries | ||
//! using this crate to have the syntax of [`Copy`][std::marker::Copy] while actually calling the | ||
//! [`Clone`][std::clone::Clone] implementation instead (usually when host library does such syntax | ||
//! in a macro). | ||
//! | ||
//! The idea is that you must implement this trait on types that are cheap to clone | ||
//! ([`std::rc::Rc`][std::rc::Rc] and [`std::sync::Arc`][std::sync::Arc] types are | ||
//! automatically implemented). Then the host library must use the trait | ||
//! [`ImplicitClone`](crate::ImplicitClone) to allow their users to pass objects that will be | ||
//! cloned automatically. | ||
//! The idea is that you must implement this trait on your cheap-to-clone types, and then the host | ||
//! library using the trait will allow users to pass values of your types and they will be cloned | ||
//! automatically. | ||
//! | ||
//! Standard types that the [`ImplicitClone`](crate::ImplicitClone) is already implemented for: | ||
//! | ||
//! - [`std::rc::Rc`][std::rc::Rc] | ||
//! - [`std::sync::Arc`][std::sync::Arc] | ||
//! - Tuples with 1-12 elements, all of which are also [`ImplicitClone`](crate::ImplicitClone) | ||
//! - [`Option`][std::option::Option], where inner value is [`ImplicitClone`](crate::ImplicitClone) | ||
//! - Some built-in [`Copy`][std::marker::Copy] types, like `()`, `bool`, `&T`, etc. | ||
//! | ||
//! This crate is in the category `rust-patterns` but this is actually a Rust anti-pattern. In Rust | ||
//! the user should always handle borrowing and ownership by themselves. Nevertheless, this pattern | ||
//! is sometimes desirable. For example, UI frameworks that rely on propagating properties from | ||
//! ancestors to children will always need to use Rc'ed types to allow every child component to | ||
//! update. This is the case in React-like framework like Yew. | ||
//! ancestors to multiple children will always need to use `Rc`'d types to cheaply and concisely | ||
//! update every child component. This is the case in React-like frameworks like | ||
//! [Yew](https://yew.rs/). | ||
//! | ||
//! This crates also provide a few convenient immutable types for handling cheap-to-clone string, | ||
//! array and maps which you can find in the modules [`sync`](crate::sync) and | ||
//! This crate also provides a few convenient immutable types for handling cheap-to-clone strings, | ||
//! arrays and maps, you can find them in the modules [`sync`](crate::sync) and | ||
//! [`unsync`](crate::unsync). Those types implement [`ImplicitClone`](crate::ImplicitClone) and | ||
//! hold only types that implement [`ImplicitClone`](crate::ImplicitClone) as well. **One big | ||
//! particularity: iterating on these types yields clones of the items and not references.** This | ||
|
@@ -35,18 +43,21 @@ | |
//! [std::clone::Clone]: https://doc.rust-lang.org/std/clone/trait.Clone.html | ||
//! [std::rc::Rc]: https://doc.rust-lang.org/std/rc/struct.Rc.html | ||
//! [std::sync::Arc]: https://doc.rust-lang.org/std/sync/struct.Arc.html | ||
//! [std::option::Option]: https://doc.rust-lang.org/stable/std/option/enum.Option.html | ||
|
||
/// Thread-safe version of immutable types. | ||
pub mod sync; | ||
/// Single-threaded version of immutable types. | ||
pub mod unsync; | ||
|
||
/// Marker trait for types that can be cloned implicitly. | ||
/// Marker trait for cheap-to-clone types that should be allowed to be cloned implicitly. | ||
/// | ||
/// Behaves exactly like [`Copy`] but calls the [`Clone`] implementation instead and must be | ||
/// implemented in the host library. | ||
/// Enables host libraries to have the same syntax as [`Copy`] while calling the [`Clone`] | ||
/// implementation instead. | ||
pub trait ImplicitClone: Clone {} | ||
|
||
impl<T: ?Sized> ImplicitClone for &T {} | ||
|
||
impl<T: ImplicitClone> ImplicitClone for Option<T> {} | ||
|
||
macro_rules! impl_implicit_clone { | ||
|
@@ -62,7 +73,7 @@ impl_implicit_clone!( | |
f32, f64, | ||
bool, | ||
usize, isize, | ||
&'static str, char, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Awesome |
||
char, | ||
(), | ||
); | ||
|
||
|
@@ -119,3 +130,79 @@ macro_rules! imap_deconstruct { | |
)* | ||
}; | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
|
||
fn host_library<T: ImplicitClone>(value: &T) -> T { | ||
value.clone() | ||
} | ||
|
||
macro_rules! host_library { | ||
($a:expr) => { | ||
host_library(&$a) | ||
}; | ||
} | ||
|
||
struct NonImplicitCloneType; | ||
|
||
#[test] | ||
fn custom() { | ||
#[derive(Clone)] | ||
struct ImplicitCloneType; | ||
|
||
impl ImplicitClone for ImplicitCloneType {} | ||
|
||
host_library!(ImplicitCloneType); | ||
} | ||
|
||
#[test] | ||
fn copy_types() { | ||
macro_rules! test_all { | ||
($($t:ty),* $(,)?) => { | ||
$(host_library!(<$t>::default());)* | ||
}; | ||
} | ||
|
||
#[rustfmt::skip] | ||
test_all!( | ||
u8, u16, u32, u64, u128, | ||
i8, i16, i32, i64, i128, | ||
f32, f64, | ||
bool, | ||
usize, isize, char, | ||
(), | ||
); | ||
} | ||
|
||
#[test] | ||
fn ref_type() { | ||
host_library!(&NonImplicitCloneType); | ||
// `host_library!(NonImplicitCloneType)` doesn't compile | ||
} | ||
|
||
#[test] | ||
fn option() { | ||
host_library!(Some("foo")); | ||
// `host_library!(Some(NonImplicitCloneType));` doesn't compile | ||
} | ||
|
||
#[test] | ||
fn tuples() { | ||
host_library!((1,)); | ||
host_library!((1, 2)); | ||
host_library!((1, 2, 3)); | ||
host_library!((1, 2, 3, 4)); | ||
host_library!((1, 2, 3, 4, 5)); | ||
host_library!((1, 2, 3, 4, 5, 6)); | ||
host_library!((1, 2, 3, 4, 5, 6, 7)); | ||
host_library!((1, 2, 3, 4, 5, 6, 7, 8)); | ||
host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9)); | ||
host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); | ||
host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); | ||
host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)); | ||
// `host_library!((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13));` doesn't compile | ||
// `host_library!((NonImplicitCloneType,));` doesn't compile | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like very much the new wording 👍 thanks!