Derive Macro qualia_derive::ObjectShape
source · #[derive(ObjectShape)]
{
// Attributes available to this derive:
#[field]
#[fixed_fields]
#[rest_fields]
#[related]
#[referenced]
}
Expand description
Automatically translate between properties of Qualia objects and fields of structs.
Basic example
#[derive(Debug, ObjectShape, PartialEq)]
struct CustomShape {
name: String,
width: i64,
}
let shape: Object = CustomShape {
name: "letter".to_string(),
width: 8,
}
.into();
assert_eq!(
shape,
object!("name" => "letter", "width" => 8),
);
let obj: Object = object!(
"name" => "letter",
"width" => 8,
);
assert_eq!(
CustomShape::try_from(obj),
Ok(CustomShape {
name: "letter".to_string(),
width: 8,
})
);
Renaming properties
By default, properties get the same name as the field in the struct. This can be changed with
the field
attribute:
#[derive(Debug, ObjectShape, PartialEq)]
struct CustomShape {
#[field("my-name")]
name: String,
width: i64,
}
let shape: Object = CustomShape {
name: "letter".to_string(),
width: 8,
}
.into();
assert_eq!(
shape,
object!("my-name" => "letter", "width" => 8),
);
Adding fixed properties
Additional fields with fixed values can be added with the fixed_fields
attribute on
the struct:
#[derive(Debug, ObjectShape, PartialEq)]
#[fixed_fields("kind" => "custom")]
struct CustomShape {
width: i64,
height: i64,
}
let shape: Object = CustomShape {
width: 8,
height: 11,
}
.into();
assert_eq!(
shape,
object!("kind" => "custom", "width" => 8, "height" => 11),
);
There is a helper method provided, q()
, which makes use of
these fields. For example, for the above object shape, CustomShape::q
returns a query for
"kind" = "custom"
.
Accessing other properties
To set and fetch unlisted properties, an Object
field with the
rest_fields
attribute may be added.
#[derive(Debug, ObjectShape, PartialEq)]
struct CustomShape {
width: i64,
#[rest_fields]
rest: Object,
}
let shape: Object = CustomShape {
width: 8,
rest: object!("height" => "tall"),
}
.into();
assert_eq!(
shape,
object!("width" => 8, "height" => "tall"),
);
Getting ID of inserted object
The ID of the object can be retrieved from an Option<i64>
field named object_id
:
#[derive(Debug, ObjectShape, PartialEq)]
struct CustomShape {
object_id: Option<i64>,
width: i64,
}
let shape: CustomShape = object!(
"object_id" => 42,
"width" => 65,
).try_into().unwrap();
assert_eq!(
shape,
CustomShape { object_id: Some(42), width: 65 },
);
// let shape2 = CustomShape { object_id: None, width: 11 };
// store.insert_with_id(&mut shape2)?;
// assert!(shape2.object_id.is_some());
Accessing related objects
Often, objects contain references to other object’s ID fields. If those objects have a defined
ObjectShape
, then helper methods to fetch them can be generated with the related
attribute:
#[derive(Debug, ObjectShape, PartialEq)]
struct ShapeGroup {
object_id: Option<i64>,
name: String,
}
#[derive(Debug, ObjectShape, PartialEq)]
struct CustomShape {
#[related(ShapeGroup)]
shape_group_id: i64,
width: i64,
}
// if let Some(group) = custom_shape.fetch_shape_group(&store)? {;
// ...