summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs407
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 _)
- }
-}