diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 407 |
1 files changed, 0 insertions, 407 deletions
diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 7c5f016..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,407 +0,0 @@ -//! A crate for creating safe self-referencing structs. -//! -//! See the documentation of [`ouroboros_examples`](https://docs.rs/ouroboros_examples) for -//! sample documentation of structs which have had the macro applied to them. - -#![no_std] -#![allow(clippy::needless_doctest_main)] - -/// This macro is used to turn a regular struct into a self-referencing one. An example: -/// ```rust -/// use ouroboros::self_referencing; -/// -/// #[self_referencing] -/// struct MyStruct { -/// int_data: i32, -/// float_data: f32, -/// #[borrows(int_data)] -/// // the 'this lifetime is created by the #[self_referencing] macro -/// // and should be used on all references marked by the #[borrows] macro -/// int_reference: &'this i32, -/// #[borrows(mut float_data)] -/// float_reference: &'this mut f32, -/// } -/// -/// fn main() { -/// // The builder is created by the #[self_referencing] macro -/// // and is used to create the struct -/// let mut my_value = MyStructBuilder { -/// int_data: 42, -/// float_data: 3.14, -/// -/// // Note that the name of the field in the builder -/// // is the name of the field in the struct + `_builder` -/// // ie: {field_name}_builder -/// // the closure that assigns the value for the field will be passed -/// // a reference to the field(s) defined in the #[borrows] macro -/// -/// int_reference_builder: |int_data: &i32| int_data, -/// float_reference_builder: |float_data: &mut f32| float_data, -/// }.build(); -/// -/// // The fields in the original struct can not be accesed directly -/// // The builder creates accessor methods which are called borrow_{field_name}() -/// -/// // Prints 42 -/// println!("{:?}", my_value.borrow_int_data()); -/// // Prints 3.14 -/// println!("{:?}", my_value.borrow_float_reference()); -/// // Sets the value of float_data to 84.0 -/// my_value.with_mut(|fields| { -/// **fields.float_reference = (**fields.int_reference as f32) * 2.0; -/// }); -/// -/// // We can hold on to this reference... -/// let int_ref = *my_value.borrow_int_reference(); -/// println!("{:?}", *int_ref); -/// // As long as the struct is still alive. -/// drop(my_value); -/// // This will cause an error! -/// // println!("{:?}", *int_ref); -/// } -/// ``` -/// To explain the features and limitations of this crate, some definitions are necessary: -/// # Definitions -/// - **immutably borrowed field**: a field which is immutably borrowed by at least one other field. -/// - **mutably borrowed field**: a field which is mutably borrowed by exactly one other field. -/// - **self-referencing field**: a field which borrows at least one other field. -/// - **head field**: a field which does not borrow any other fields, I.E. not self-referencing. -/// This does not include fields with empty borrows annotations (`#[borrows()]`.) -/// - **tail field**: a field which is not borrowed by any other fields. -/// -/// # Usage -/// To make a self-referencing struct, you must write a struct definition and place -/// `#[self_referencing]` on top. For every field that borrows other fields, you must place -/// `#[borrows()]` on top and place inside the parenthesis a list of fields that it borrows. Mut can -/// be prefixed to indicate that a mutable borrow is required. For example, -/// `#[borrows(a, b, mut c)]` indicates that the first two fields need to be borrowed immutably and -/// the third needs to be borrowed mutably. You can also use `#[borrows()]` without any arguments to -/// indicate a field that will eventually borrow from the struct, but does not borrow anything when -/// first created. For example, you could use this on a field like `error: Option<&'this str>`. -/// -/// # You must comply with these limitations -/// - Fields must be declared before the first time they are borrowed. -/// - Normal borrowing rules apply, E.G. a field cannot be borrowed mutably twice. -/// - Fields that use the `'this` lifetime must have a corresponding `#[borrows()]` annotation. -/// The error for this needs some work, currently you will get an error saying that `'this` is -/// undefined at the location it was illegally used in. -/// -/// Violating them will result in an error message directly pointing out the violated rule. -/// -/// # Flexibility of this crate -/// The example above uses plain references as the self-referencing part of the struct, but you can -/// use anything that is dependent on lifetimes of objects inside the struct. For example, you could -/// do something like this: -/// ```rust -/// use ouroboros::self_referencing; -/// -/// pub struct ComplexData<'a, 'b> { -/// aref: &'a i32, -/// bref: &'b mut i32, -/// number: i32, -/// } -/// -/// impl<'a, 'b> ComplexData<'a, 'b> { -/// fn new(aref: &'a i32, bref: &'b mut i32, number: i32) -> Self { -/// Self { aref, bref, number } -/// } -/// -/// /// Copies the value aref points to into what bref points to. -/// fn transfer(&mut self) { -/// *self.bref = *self.aref; -/// } -/// -/// /// Prints the value bref points to. -/// fn print_bref(&self) { -/// println!("{}", *self.bref); -/// } -/// } -/// -/// fn main() { -/// #[self_referencing] -/// struct DataStorage { -/// immutable: i32, -/// mutable: i32, -/// #[borrows(immutable, mut mutable)] -/// #[covariant] -/// complex_data: ComplexData<'this, 'this>, -/// } -/// -/// let mut data_storage = DataStorageBuilder { -/// immutable: 10, -/// mutable: 20, -/// complex_data_builder: |i: &i32, m: &mut i32| ComplexData::new(i, m, 12345), -/// }.build(); -/// data_storage.with_complex_data_mut(|data| { -/// // Copies the value in immutable into mutable. -/// data.transfer(); -/// // Prints 10 -/// data.print_bref(); -/// }); -/// } -/// ``` -/// -/// # Note on memory leaks -/// Currently, if a builder panics when creating a field, all previous fields will be leaked. This -/// does not cause any undefined behavior. This behavior may be resolved in the future so that all -/// previous fields are dropped when a builder panics. -/// -/// # Covariance -/// Many types in Rust have a property called "covariance". In practical tearms, this means that a -/// covariant type like `Box<&'this i32>` can be used as a `Box<&'a i32>` as long as `'a` is -/// smaller than `'this`. Since the lifetime is smaller, it does not violate the lifetime specified -/// by the original type. Contrast this to `Fn(&'this i32)`, which is not covariant. You cannot give -/// this function a reference with a lifetime shorter than `'this` as the function needs something -/// that lives at *least* as long as `'this`. Unfortunately, there is no easy way to determine -/// whether or not a type is covariant from inside the macro. As such, you may -/// receive a compiler error letting you know that the macro is uncertain if a particular field -/// uses a covariant type. Adding `#[covariant]` or `#[not_covariant]` will resolve this issue. -/// -/// These annotations control whether or not a `borrow_*` method is generated for that field. -/// Incorrectly using one of these tags will result in a compilation error. It is impossible to -/// use them unsoundly. -/// -/// # Async usage -/// All self-referencing structs can be initialized asynchronously by using either the -/// `MyStruct::new_async()` function or the `MyStructAsyncBuilder` builder. Due to limitations of -/// the rust compiler you closures must return a Future trait object wrapped in a `Pin<Box<_>>`. -/// -/// Here is the same example as above in its async version: -/// -/// ```ignore -/// use ouroboros::self_referencing; -/// -/// #[self_referencing] -/// struct MyStruct { -/// int_data: i32, -/// float_data: f32, -/// #[borrows(int_data)] -/// int_reference: &'this i32, -/// #[borrows(mut float_data)] -/// float_reference: &'this mut f32, -/// } -/// -/// #[tokio::main] -/// async fn main() { -/// let mut my_value = MyStructAsyncBuilder { -/// int_data: 42, -/// float_data: 3.14, -/// int_reference_builder: |int_data: &i32| Box::pin(async move { int_data }), -/// float_reference_builder: |float_data: &mut f32| Box::pin(async move { float_data }), -/// }.build().await; -/// -/// // Prints 42 -/// println!("{:?}", my_value.borrow_int_data()); -/// // Prints 3.14 -/// println!("{:?}", my_value.borrow_float_reference()); -/// // Sets the value of float_data to 84.0 -/// my_value.with_mut(|fields| { -/// **fields.float_reference = (**fields.int_reference as f32) * 2.0; -/// }); -/// -/// // We can hold on to this reference... -/// let int_ref = *my_value.borrow_int_reference(); -/// println!("{:?}", *int_ref); -/// // As long as the struct is still alive. -/// drop(my_value); -/// // This will cause an error! -/// // println!("{:?}", *int_ref); -/// } -/// ``` -/// -/// # Async Send -/// When Send trait is needed, the Send variant of async methods and builders is available. -/// -/// Here is the same example as above in its async send version: -/// -/// ```ignore -/// use ouroboros::self_referencing; -/// -/// #[self_referencing] -/// struct MyStruct { -/// int_data: i32, -/// float_data: f32, -/// #[borrows(int_data)] -/// int_reference: &'this i32, -/// #[borrows(mut float_data)] -/// float_reference: &'this mut f32, -/// } -/// -/// #[tokio::main] -/// async fn main() { -/// let mut my_value = MyStructAsyncSendBuilder { -/// int_data: 42, -/// float_data: 3.14, -/// int_reference_builder: |int_data: &i32| Box::pin(async move { int_data }), -/// float_reference_builder: |float_data: &mut f32| Box::pin(async move { float_data }), -/// }.build().await; -/// -/// // Prints 42 -/// println!("{:?}", my_value.borrow_int_data()); -/// // Prints 3.14 -/// println!("{:?}", my_value.borrow_float_reference()); -/// // Sets the value of float_data to 84.0 -/// my_value.with_mut(|fields| { -/// **fields.float_reference = (**fields.int_reference as f32) * 2.0; -/// }); -/// -/// // We can hold on to this reference... -/// let int_ref = *my_value.borrow_int_reference(); -/// println!("{:?}", *int_ref); -/// // As long as the struct is still alive. -/// drop(my_value); -/// // This will cause an error! -/// // println!("{:?}", *int_ref); -/// } -/// ``` -/// -/// # What does the macro generate? -/// The `#[self_referencing]` struct will replace your definition with an unsafe self-referencing -/// struct with a safe public interface. Many functions will be generated depending on your original -/// struct definition. Documentation is generated for all items, so building documentation for -/// your project allows accessing detailed information about available functions. Using -/// `#[self_referencing(no_doc)]` will hide the generated items from documentation if it is becoming -/// too cluttered. -/// -/// ### A quick note on visibility -/// The visibility of generated items is dependent on one of two things. If the -/// generated item is related to a specific field of the struct, it uses the visibility of the -/// original field. (The actual field in the struct will be made private since accessing it could cause -/// undefined behavior.) If the generated item is not related to any particular field, it will by -/// default only be visible to the module the struct is declared in. (This includes things like -/// `new()` and `with()`.) You can use `#[self_referencing(pub_extras)]` to make these items have the -/// same visibility as the struct itself. -/// -/// # List of generated items -/// ### `MyStruct::new(fields...) -> MyStruct` -/// A basic constructor. It accepts values for each field in the order you declared them in. For -/// **head fields**, you only need to pass in what value it should have and it will be moved in -/// to the output. For **self-referencing fields**, you must provide a function or closure which creates -/// the value based on the values it borrows. A field using the earlier example of -/// `#[borrow(a, b, mut c)]` would require a function typed as -/// `FnOnce(a: &_, b: &_, c: &mut _) -> _`. Fields which have an empty borrows annotation -/// (`#[borrows()]`) should have their value directly passed in. A field using the earlier example -/// of `Option<&'this str>` would require an input of `None`. Do not pass a function. Do not collect -/// 200 dollars. -/// ### `MyStruct::new_async(fields...) -> MyStruct` -/// A basic async constructor. It works identically to the sync constructor differing only in the -/// type of closures it expects. Whenever a closure is required it is expected to return a Pinned -/// and Boxed Future that Outputs the same type as the synchronous version. -/// ### `MyStruct::new_async_send(fields...) -> MyStruct` -/// An async send constructor. It works identically to the sync constructor differing only in the -/// Send trait being specified in the return type. -/// ### `MyStructBuilder` -/// This is the preferred way to create a new instance of your struct. It is similar to using the -/// `MyStruct { a, b, c, d }` syntax instead of `MyStruct::new(a, b, c, d)`. It contains one field -/// for every argument in the actual constructor. **Head fields** have the same name that you -/// originally defined them with. **self-referencing fields** are suffixed with `_builder` since you need -/// to provide a function instead of a value. Fields with an empty borrows annotation are not -/// initialized using builders. Calling `.build()` on an instance of `MyStructBuilder` -/// will convert it to an instance of `MyStruct` by calling all `_builder` functions in the order that -/// they were declared and storing their results. -/// ### `MyStructAsyncBuilder` -/// This is the preferred way to asynchronously create a new instance of your struct. It works -/// identically to the synchronous builder differing only in the type of closures it expects. In -/// particular, all builder functions are called serially in the order that they were declared. -/// Whenever a closure is required it is expected to return a Pinned and Boxed Future that Outputs -/// the same type as the synchronous version. -/// ### `MyStructAsyncSendBuilder` -/// Same as MyStructAsyncBuilder, but with Send trait specified in the return type. -/// ### `MyStruct::try_new<E>(fields...) -> Result<MyStruct, E>` -/// Similar to the regular `new()` function, except the functions wich create values for all -/// **self-referencing fields** can return `Result<>`s. If any of those are `Err`s, that error will be -/// returned instead of an instance of `MyStruct`. The preferred way to use this function is through -/// `MyStructTryBuilder` and its `try_build()` function. -/// ### `MyStruct::try_new_async<E>(fields...) -> Result<MyStruct, E>` -/// Similar to the regular `new_async()` function, except the functions wich create values for all -/// **self-referencing fields** can return `Result<>`s. If any of those are `Err`s, that error will be -/// returned instead of an instance of `MyStruct`. The preferred way to use this function is through -/// `MyStructAsyncTryBuilder` and its `try_build()` function. -/// ### `MyStruct::try_new_async_send<E>(fields...) -> Result<MyStruct, E>` -/// Same as `new_async()` function, but with Send trait specified in the return type. -/// ### `MyStruct::try_new_or_recover_async<E>(fields...) -> Result<MyStruct, (E, Heads)>` -/// Similar to the `try_new_async()` function, except that all the **head fields** are returned along side -/// the original error in case of an error. The preferred way to use this function is through -/// `MyStructAsyncTryBuilder` and its `try_build_or_recover()` function. -/// ### `MyStruct::try_new_or_recover_async_send<E>(fields...) -> Result<MyStruct, (E, Heads)>` -/// Same as `try_new_or_recover_async()` function, but with Send trait specified in the return type. -/// ### `MyStruct::with_FIELD<R>(&self, user: FnOnce(field: &FieldType) -> R) -> R` -/// This function is generated for every **tail and immutably-borrowed field** in your struct. It -/// allows safely accessing -/// a reference to that value. The function generates the reference and passes it to `user`. You -/// can do anything you want with the reference, it is constructed to not outlive the struct. -/// ### `MyStruct::borrow_FIELD(&self) -> &FieldType` -/// This function is generated for every **tail and immutably-borrowed field** in your struct. It -/// is equivalent to calling `my_struct.with_FIELD(|field| field)`. It is only generated for types -/// which are known to be covariant, either through the macro being able to detect it or through the -/// programmer adding the `#[covariant]` annotation to the field. -/// There is no `borrow_FIELD_mut`, unfortunately, as Rust's -/// borrow checker is currently not capable of ensuring that such a method would be used safely. -/// ### `MyStruct::with_FIELD_mut<R>(&mut self, user: FnOnce(field: &mut FieldType) -> R) -> R` -/// This function is generated for every **tail field** in your struct. It is the mutable version -/// of `with_FIELD`. -/// ### `MyStruct::with<R>(&self, user: FnOnce(fields: AllFields) -> R) -> R` -/// Allows borrowing all **tail and immutably-borrowed fields** at once. Functions similarly to -/// `with_FIELD`. -/// ### `MyStruct::with_mut<R>(&self, user: FnOnce(fields: AllFields) -> R) -> R` -/// Allows mutably borrowing all **tail fields** and immutably borrowing all **immutably-borrowed** -/// fields at once. Functions similarly to `with_FIELD_mut`, except that you can borrow multiple -/// fields as mutable at the same time and also have immutable access to any remaining fields. -/// ### `MyStruct::into_heads(self) -> Heads` -/// Drops all self-referencing fields and returns a struct containing all **head fields**. -pub use ouroboros_macro::self_referencing; - -#[doc(hidden)] -pub mod macro_help { - pub extern crate alloc; - - pub use aliasable::boxed::AliasableBox; - use aliasable::boxed::UniqueBox; - - pub struct CheckIfTypeIsStd<T>(core::marker::PhantomData<T>); - - macro_rules! std_type_check { - ($fn_name:ident $T:ident $check_for:ty) => { - impl<$T: ?Sized> CheckIfTypeIsStd<$check_for> { - pub fn $fn_name() {} - } - }; - } - - std_type_check!(is_std_box_type T alloc::boxed::Box<T>); - std_type_check!(is_std_arc_type T alloc::sync::Arc<T>); - std_type_check!(is_std_rc_type T alloc::rc::Rc<T>); - - pub fn aliasable_boxed<T>(data: T) -> AliasableBox<T> { - AliasableBox::from_unique(UniqueBox::new(data)) - } - - pub fn unbox<T>(boxed: AliasableBox<T>) -> T { - *AliasableBox::into_unique(boxed) - } - - /// Converts a reference to an object to a static reference This is - /// obviously unsafe because the compiler can no longer guarantee that the - /// data outlives the reference. It is up to the consumer to get rid of the - /// reference before the container is dropped. The + 'static ensures that - /// whatever we are referring to will remain valid indefinitely, that there - /// are no limitations on how long the pointer itself can live. - /// - /// # Safety - /// - /// The caller must ensure that the returned reference is not used after the originally passed - /// reference would become invalid. - pub unsafe fn change_lifetime<'old, 'new: 'old, T: 'new>(data: &'old T) -> &'new T { - &*(data as *const _) - } - - /// Like change_lifetime, but for mutable references. - /// - /// # Safety - /// - /// The caller must ensure that the returned reference is not used after the originally passed - /// reference would become invalid. - pub unsafe fn change_lifetime_mut<'old, 'new: 'old, T: 'new>(data: &'old mut T) -> &'new mut T { - &mut *(data as *mut _) - } -} |