oors-macros 0.8.1

Macros for oors -- See https://crates.io/crates/oors
Documentation
/*
 * Copyright (c) 2025 eligamii.
 * Licenced under the MIT licence. See the LICENCE file in the project for full licence information
 */



mod object;
mod object_impl;

use proc_macro::TokenStream;
use crate::object::impl_object;
use crate::object_impl::impl_object_impl;

/// Add inheritance capabilities to your struct.
///
/// # Syntax
/// ```ignore
/// #[oors::object]
/// struct T { /* ... */ }
///
/// #[oors::object(parent = T)]
/// struct T2 { /* ... */ } // First field will be _base: T
/// ```
/// ---
///
/// # How it works
/// This macro will generate and implement various traits + a macro to allow structs to be
/// safely converted to other compatible structs:
/// - `IsA</* immediate parent */> for T`: Allows at compile time for `T` to have access to parent
///     structs' methods and fields, and to be safely converted to parent structs
/// - `__*Accessors`: Methods to have direct and easy access to field of `T` and all its parents
/// - `__*Builders`: Methods to easily initialize the struct using the builder pattern
/// - `__oors_recursive_impl_*!(/* type */)`: Generated macro to implement `IsA</* all parents of T */>` to `T` and its children
/// 
/// - `Object`: Allows at runtime to know what is the actual type + the parents of `T` when inside a `Typed<T>`
///
/// **Notes:**<br/>
/// - This macro will also cause the object to have a C layout (`#[repr(C)]`) to ensure predictability
/// - If you inherit from an object (`C`) from a foreign module/crate (`mod1`), this macro requires importing the module and all
/// modules containing parent of `C` using the wildcard syntax:
/// ```ignore
/// // prefer `pub use` so other modules doesn't have to `use` `mod1` or `parent_of_c`
/// // to make a child struct of `D`
/// pub use mod1::*;
/// pub use crate_b::parent_of_c::*;
///
/// // Will use __oors_recursive_impl_C!(...) which
/// // will use __oors_recursive_impl_<parent of C>!()
/// // etc.
/// #[oors::object(parent = C)]
/// struct D;
/// ```
#[proc_macro_attribute]
pub fn object(attr: TokenStream, item: TokenStream) -> TokenStream {
    // Impl the IsA</* parent type */> trait
    // Adds a field _parent_name_snake_case: ParentType
    // Makes the struct #[repr(C)]
    // Generate a __StructAccessors that will give access to all fields with methods (StructImpl::name(), ::name_mut())
    // The __StructAccessors is impl for all IsA<Struct> and uses the Struct's fields offset + pointer magic to access
    // values
    // Generate a __StructBuilder to allow for the struct to be initialized
    impl_object(attr, item)
}


/// Generate implementation for both a struct itself and any child type of the struct.
///
/// # Syntax
/// ```ignore
/// struct T;
/// #[oors::object_impl] impl T { /* ... */ }
/// #[oors::object_impl(pub)] impl T { /* ... */ }
/// #[oors::object_impl(/* any visibility modifier */)] impl T { /* ... */ }
/// ```
///
/// ---
///
/// # How it works
/// It simply automatically puts every instance methods into a generated `<visibility modifier> trait __TImpl where Self: IsA<T>` trait.

#[proc_macro_attribute]/// The visibility modifier is for the 
pub fn object_impl(attr: TokenStream, item: TokenStream) -> TokenStream {
    // Change the signature from
    // "impl Class { /* items */ }"
    // to
    // "pub trait ClassImpl: IsA<Class> { /* funcs using self */ } impl<T: IsA<Class>> ClassImpl for T"
    // and
    // "impl Class { /* any other items */ }"
    impl_object_impl(attr, item)
}