pub struct Box<T: ?Sized + 'static> { /* private fields */ }
Expand description
A linked object that acts like a std::boxed::Box<dyn MyTrait>
.
Intended to represent linked instances of T
where T: MyTrait
. This is for use with types
that are always exposed to user code as trait objects via linked::Box<dyn MyTrait>
.
The Box
itself implements the linked object API from #[linked::object]
. The type
T
is not decorated with the #[linked::object]
attribute when using Box
and simply
uses linked object patterns in its constructor.
§Usage
Use it like a regular std::boxed::Box<T>
that also happens to support the linked object
patterns. The box can be used via all the standard mechanisms such as:
linked::instances!
linked::thread_local_rc!
linked::thread_local_arc!
(ifT: Sync
)linked::InstancePerThread<T>
linked::InstancePerThreadSync<T>
(ifT: Sync
)linked::Family<T>
§Implementation
Instead of a typical constructor, create one that returns linked::Box<dyn MyTrait>
. Inside
this constructor, create a linked::Box
instance using the linked::new_box!
macro.
The first macro parameter is the type of the trait object inside the box, and the second is a
Self
struct-expression to create one linked instance of the implementation type.
// If using linked::Box, do not put `#[linked::object]` on the struct.
// The linked::Box itself is the linked object and our struct is only its contents.
struct XmlConfig {
config: String,
}
impl XmlConfig {
pub fn new_as_config_source() -> linked::Box<dyn ConfigSource> {
// Constructing instances works logically the same as for regular linked objects.
//
// The only differences are:
// 1. We use `linked::new_box!` instead of `linked::new!`
// 2. There is an additional parameter to the macro to name the trait object type
linked::new_box!(
dyn ConfigSource,
Self {
config: "xml".to_string(),
}
)
}
}
Any connections between the instances should be established via the captured state of this
closure (e.g. sharing an Arc
or setting up messaging channels).
§Example
Using the linked objects as linked::Box<dyn ConfigSource>
, without the user code knowing the
exact type of the object in the box:
trait ConfigSource {
fn config(&self) -> String;
}
struct XmlConfig {}
struct IniConfig {}
impl ConfigSource for XmlConfig {
fn config(&self) -> String {
"xml".to_string()
}
}
impl ConfigSource for IniConfig {
fn config(&self) -> String {
"ini".to_string()
}
}
impl XmlConfig {
pub fn new_as_config_source() -> linked::Box<dyn ConfigSource> {
linked::new_box!(dyn ConfigSource, XmlConfig {})
}
}
impl IniConfig {
pub fn new_as_config_source() -> linked::Box<dyn ConfigSource> {
linked::new_box!(dyn ConfigSource, IniConfig {})
}
}
let xml_config = XmlConfig::new_as_config_source();
let ini_config = IniConfig::new_as_config_source();
let configs: [linked::Box<dyn ConfigSource>; 2] = [xml_config, ini_config];
assert_eq!(configs[0].config(), "xml".to_string());
assert_eq!(configs[1].config(), "ini".to_string());