### Handle Auto Traits Send, Sync, Unpin Source: https://context7.com/quartiq/crosstrait/llms.txt Auto traits like `Send`, `Sync`, and `Unpin` create distinct trait objects. Each combination must be registered separately if needed. This example shows how `dyn Debug` is registered, but `dyn Debug + Sync` is not. ```rust use core::any::Any; use crosstrait::{register, Cast}; use core::fmt::Debug; register! { i32 => dyn Debug } // Note: dyn Debug + Sync is a different trait object // register! { i32 => dyn Debug + Sync } let any: &dyn Any = &42i32; // This works - plain Debug is registered let a: Option<&dyn Debug> = any.cast(); assert!(a.is_some()); // This returns None - Debug + Sync is not registered let b: Option<&(dyn Debug + Sync)> = any.cast(); assert!(b.is_none()); ``` -------------------------------- ### Create Custom Registry with entry! Macro Source: https://context7.com/quartiq/crosstrait/llms.txt Use `Registry::new()` with the `entry!` macro to build custom registries for specific use cases. These registries do not use the global registry and must be passed explicitly. ```rust use core::any::Any; use crosstrait::{entry, Registry}; use core::fmt::Debug; // Build a custom registry with specific entries let custom_registry = Registry::new(&[ entry!(i32 => dyn Debug), entry!(String => dyn Debug), ]); let any: &dyn Any = &42i32; let debug_ref: &dyn Debug = custom_registry.cast_ref(any).unwrap(); println!("Custom registry: {:?}", debug_ref); // String is also registered in this custom registry let any_str: &dyn Any = &String::from("hello"); let debug_str: &dyn Debug = custom_registry.cast_ref(any_str).unwrap(); println!("String via custom: {:?}", debug_str); ``` -------------------------------- ### Add crosstrait dependency Source: https://github.com/quartiq/crosstrait/blob/main/README.md Add the crate to your Cargo.toml file. ```toml [dependencies] crosstrait = "0.1" ``` -------------------------------- ### Register and cast trait objects Source: https://github.com/quartiq/crosstrait/blob/main/README.md Demonstrates registering types to traits and performing various cast operations including references, mutable references, Box, Rc, and Arc. Requires the register! macro and Cast traits. ```rust use core::any::Any; use crosstrait::{Cast, Castable, CastableRef, entry, register, REGISTRY, Registry}; // Some example traits to play with use core::{fmt::{Debug, Formatter, Write}, ops::{AddAssign, SubAssign}}; // Add types and trait implementations to the default registry // Implementation status is verified at compile time register! { i32 => dyn Debug } // Registering foreign types and traits works fine // Serialization/deserialization of `dyn Any` is a major use case // register! { i32 => dyn erased_serde::Serialize } // If a type is not Send + Sync, it can't cast as Arc. // `no_arc` accounts for that register! { Formatter => dyn Write, no_arc } // Check for trait impl registration on concrete type assert!(i32::castable::()); // Check for trait impl registration on Any let any: &dyn Any = &42i32; assert!(any.castable::()); // SubAssign is impl'd for i32 but not registered assert!(!any.castable::>()); // Cast ref let a: &dyn Debug = any.cast().unwrap(); println!("42 = {a:?}"); // Cast mut let mut value = 5i32; let any: &mut dyn Any = &mut value; let v: &mut dyn AddAssign = any.cast().unwrap(); *v += 3; assert_eq!(value, 5 + 3); // Cast Box let any: Box = Box::new(0i32); let _: Box = any.cast().unwrap(); // Cast Rc use std::rc::Rc; let any: Rc = Rc::new(0i32); let _: Rc = any.cast().unwrap(); // Cast Arc use std::sync::Arc; let any: Arc = Arc::new(0i32); let _: Arc = any.cast().unwrap(); // Explicit registry usage let any: &dyn Any = &0i32; let _: &dyn Debug = REGISTRY.cast_ref(any).unwrap(); // Custom non-static registry let myreg = Registry::new(&[entry!(i32 => dyn Debug)]); let _: &dyn Debug = myreg.cast_ref(any).unwrap(); // Autotraits and type/const generics are distinct let a: Option<&(dyn Debug + Sync)> = any.cast(); assert!(a.is_none()); // Registration in the default registry can happen anywhere // in any order in any downstream crate register! { i32 => dyn AddAssign } ``` -------------------------------- ### register! Macro Source: https://context7.com/quartiq/crosstrait/llms.txt The `register!` macro is used to add type-trait pairs to the global registry. This registration is verified at compile time. The `no_arc` flag can be used for types that do not implement `Send + Sync`. ```APIDOC ## register! Macro - Register Type-Trait Pairs The `register!` macro adds a type and its trait implementation to the global registry. This registration is verified at compile time, ensuring the type actually implements the specified trait. Use the `no_arc` flag for types that don't implement `Send + Sync`. ```rust use crosstrait::register; use core::fmt::Debug; use core::ops::AddAssign; // Register i32 as castable to Debug register! { i32 => dyn Debug } // Register with no_arc flag for non-Send+Sync types use core::fmt::{Formatter, Write}; register! { Formatter => dyn Write, no_arc } // Registration can happen anywhere in any downstream crate register! { i32 => dyn AddAssign } // Register foreign types and traits (e.g., for serialization) // register! { i32 => dyn erased_serde::Serialize } ``` ``` -------------------------------- ### Registry Methods for Casting Source: https://context7.com/quartiq/crosstrait/llms.txt The `Registry` struct provides methods for checking castability and performing casts for various pointer types. This includes checking references, concrete types, Boxes, Rcs, and Arcs. ```rust use core::any::Any; use std::rc::Rc; use std::sync::Arc; use crosstrait::{entry, Registry}; use core::fmt::Debug; let registry = Registry::new(&[entry!(i32 => dyn Debug)]); // castable_ref - check if Any can be cast let any: &dyn Any = &42i32; assert!(registry.castable_ref::(any)); // castable - check if concrete type can be cast assert!(registry.castable::()); // cast_ref - cast immutable reference let r: &dyn Debug = registry.cast_ref(any).unwrap(); // cast_mut - cast mutable reference let mut val = 42i32; let any_mut: &mut dyn Any = &mut val; let _: &mut dyn Debug = registry.cast_mut(any_mut).unwrap(); // cast_box - cast Box (returns Result) let boxed: Box = Box::new(42i32); let _: Box = registry.cast_box(boxed).unwrap(); // cast_rc - cast Rc (returns Result) let rc: Rc = Rc::new(42i32); let _: Rc = registry.cast_rc(rc).unwrap(); // cast_arc - cast Arc (returns Result) let arc: Arc = Arc::new(42i32); let _: Arc = registry.cast_arc(arc).unwrap(); ``` -------------------------------- ### Registry - Explicit Usage Source: https://context7.com/quartiq/crosstrait/llms.txt The global `REGISTRY` can be used explicitly for casting operations, providing direct access to the registry's casting methods. ```APIDOC ## Registry - Explicit Registry Usage The global `REGISTRY` can be used explicitly for casting operations. This provides direct access to the registry's casting methods. ```rust use core::any::Any; use crosstrait::{register, REGISTRY}; use core::fmt::Debug; register! { i32 => dyn Debug } let any: &dyn Any = &42i32; // Use REGISTRY explicitly let debug_ref: &dyn Debug = REGISTRY.cast_ref(any).unwrap(); println!("Via REGISTRY: {:?}", debug_ref); // Check castability via registry assert!(REGISTRY.castable_ref::(any)); assert!(REGISTRY.castable::()); ``` ``` -------------------------------- ### Register Type-Trait Pairs with `register!` Macro Source: https://context7.com/quartiq/crosstrait/llms.txt Use the `register!` macro to add type-trait pairs to the global registry. This registration is verified at compile time. Use the `no_arc` flag for types that do not implement `Send + Sync`. ```rust use crosstrait::register; use core::fmt::Debug; use core::ops::AddAssign; // Register i32 as castable to Debug register! { i32 => dyn Debug } // Register with no_arc flag for non-Send+Sync types use core::fmt::{Formatter, Write}; register! { Formatter => dyn Write, no_arc } // Registration can happen anywhere in any downstream crate register! { i32 => dyn AddAssign } // Register foreign types and traits (e.g., for serialization) // register! { i32 => dyn erased_serde::Serialize } ``` -------------------------------- ### Explicit Registry Usage with `REGISTRY` Source: https://context7.com/quartiq/crosstrait/llms.txt The global `REGISTRY` can be used explicitly for casting operations, providing direct access to its casting methods like `cast_ref` and `castable_ref`. Ensure the type-trait pair is registered. ```rust use core::any::Any; use crosstrait::{register, REGISTRY}; use core::fmt::Debug; register! { i32 => dyn Debug } let any: &dyn Any = &42i32; // Use REGISTRY explicitly let debug_ref: &dyn Debug = REGISTRY.cast_ref(any).unwrap(); println!("Via REGISTRY: {:?}", debug_ref); // Check castability via registry assert!(REGISTRY.castable_ref::(any)); assert!(REGISTRY.castable::()); ``` -------------------------------- ### Cast Smart Pointers (`Box`, `Rc`, `Arc`) with `Cast` Trait Source: https://context7.com/quartiq/crosstrait/llms.txt The `Cast` trait supports casting smart pointers like `Box`, `Rc`, and `Arc` to their respective trait object smart pointer types. Ensure the type-trait pair is registered. ```rust use core::any::Any; use std::rc::Rc; use std::sync::Arc; use crosstrait::{register, Cast}; use core::fmt::Debug; register! { i32 => dyn Debug } // Cast Box let any: Box = Box::new(42i32); let debug_box: Box = any.cast().unwrap(); println!("Boxed: {:?}", debug_box); // Cast Rc let any: Rc = Rc::new(42i32); let debug_rc: Rc = any.cast().unwrap(); println!("Rc: {:?}", debug_rc); // Cast Arc (requires type to be Send + Sync) let any: Arc = Arc::new(42i32); let debug_arc: Arc = any.cast().unwrap(); println!("Arc: {:?}", debug_arc); ``` -------------------------------- ### Check `dyn Any` Castability at Runtime with `CastableRef` Source: https://context7.com/quartiq/crosstrait/llms.txt The `CastableRef` trait allows checking if a `&dyn Any` reference can be cast to a specific trait object at runtime. This is useful when the concrete type is unknown. Ensure the type-trait pair is registered. ```rust use core::any::Any; use crosstrait::{register, CastableRef}; use core::fmt::Debug; use core::ops::SubAssign; register! { i32 => dyn Debug } let any: &dyn Any = &42i32; // Check castability on the Any reference assert!(any.castable::()); assert!(!any.castable::>()); ``` -------------------------------- ### Cast Trait - Smart Pointers Source: https://context7.com/quartiq/crosstrait/llms.txt The `Cast` trait also supports casting `Box`, `Rc`, and `Arc` to their respective trait object smart pointer types. ```APIDOC ## Cast Trait - Cast Smart Pointers The `Cast` trait also supports casting `Box`, `Rc`, and `Arc` to their respective trait object smart pointer types. ```rust use core::any::Any; use std::rc::Rc; use std::sync::Arc; use crosstrait::{register, Cast}; use core::fmt::Debug; register! { i32 => dyn Debug } // Cast Box let any: Box = Box::new(42i32); let debug_box: Box = any.cast().unwrap(); println!("Boxed: {:?}", debug_box); // Cast Rc let any: Rc = Rc::new(42i32); let debug_rc: Rc = any.cast().unwrap(); println!("Rc: {:?}", debug_rc); // Cast Arc (requires type to be Send + Sync) let any: Arc = Arc::new(42i32); let debug_arc: Arc = any.cast().unwrap(); println!("Arc: {:?}", debug_arc); ``` ``` -------------------------------- ### Cast `&dyn Any` and `&mut dyn Any` with `Cast` Trait Source: https://context7.com/quartiq/crosstrait/llms.txt The `Cast` trait enables casting `&dyn Any` and `&mut dyn Any` to trait object references. It returns `Option<&T>` or `Option<&mut T>`, yielding `None` if the type-trait pair is not registered. ```rust use core::any::Any; use crosstrait::{register, Cast}; use core::fmt::Debug; use core::ops::AddAssign; register! { i32 => dyn Debug } register! { i32 => dyn AddAssign } // Cast immutable reference let any: &dyn Any = &42i32; let debug_ref: &dyn Debug = any.cast().unwrap(); println!("Value: {:?}", debug_ref); // Output: Value: 42 // Cast mutable reference let mut value = 5i32; let any: &mut dyn Any = &mut value; let add_ref: &mut dyn AddAssign = any.cast().unwrap(); *add_ref += 3; assert_eq!(value, 8); ``` -------------------------------- ### Check Type Castability with `Castable` Trait Source: https://context7.com/quartiq/crosstrait/llms.txt The `Castable` trait provides a static method to check if a concrete type has been registered as castable to a given trait object using the global registry. Ensure the type-trait pair is registered before checking. ```rust use crosstrait::{register, Castable}; use core::fmt::Debug; use core::ops::SubAssign; register! { i32 => dyn Debug } // Check if i32 is registered as castable to Debug assert!(i32::castable::()); // SubAssign is implemented but not registered assert!(!i32::castable::>()); ``` -------------------------------- ### Castable Trait Source: https://context7.com/quartiq/crosstrait/llms.txt The `Castable` trait provides a static method to check if a concrete type has been registered as castable to a given trait object using the global registry. ```APIDOC ## Castable Trait - Check Type Castability The `Castable` trait provides a static method to check whether a concrete type has been registered as castable to a given trait object. This check uses the global registry. ```rust use crosstrait::{register, Castable}; use core::fmt::Debug; use core::ops::SubAssign; register! { i32 => dyn Debug } // Check if i32 is registered as castable to Debug assert!(i32::castable::()); // SubAssign is implemented but not registered assert!(!i32::castable::>()); ``` ``` -------------------------------- ### Cast Trait - References Source: https://context7.com/quartiq/crosstrait/llms.txt The `Cast` trait enables casting `&dyn Any` and `&mut dyn Any` to trait object references. The cast returns `Option<&T>` or `Option<&mut T>`, returning `None` if the type-trait pair isn't registered. ```APIDOC ## Cast Trait - Cast References The `Cast` trait enables casting `&dyn Any` and `&mut dyn Any` to trait object references. The cast returns `Option<&T>` or `Option<&mut T>`, returning `None` if the type-trait pair isn't registered. ```rust use core::any::Any; use crosstrait::{register, Cast}; use core::fmt::Debug; use core::ops::AddAssign; register! { i32 => dyn Debug } register! { i32 => dyn AddAssign } // Cast immutable reference let any: &dyn Any = &42i32; let debug_ref: &dyn Debug = any.cast().unwrap(); println!("Value: {:?}", debug_ref); // Output: Value: 42 // Cast mutable reference let mut value = 5i32; let any: &mut dyn Any = &mut value; let add_ref: &mut dyn AddAssign = any.cast().unwrap(); *add_ref += 3; assert_eq!(value, 8); ``` ``` -------------------------------- ### CastableRef Trait Source: https://context7.com/quartiq/crosstrait/llms.txt The `CastableRef` trait allows checking if a `&dyn Any` reference can be cast to a specific trait object at runtime. This is useful when the concrete type is unknown. ```APIDOC ## CastableRef Trait - Check Any Castability at Runtime The `CastableRef` trait allows checking whether a `&dyn Any` reference can be cast to a specific trait object at runtime. This is useful when the concrete type is unknown. ```rust use core::any::Any; use crosstrait::{register, CastableRef}; use core::fmt::Debug; use core::ops::SubAssign; register! { i32 => dyn Debug } let any: &dyn Any = &42i32; // Check castability on the Any reference assert!(any.castable::()); assert!(!any.castable::>()); ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.