use alux_ext::ext;
use alux_ext::macros::shape;
use alux_shape::{FieldAlg, ShapeAlg, ShapeDeclareExt, ShapeExt, ShapeProgramExt, Sorts};
use alux_shape_text::TextShape;
#[ext(name = LeafExt, supertraits = Sorts + Sized)]
pub impl<This> This
where
This: ShapeAlg,
{
fn checksum(&self) -> Self::Ty {
self.bytes_hex(Some(32))
}
fn amount(&self) -> Self::Ty {
self.int_decimal(false, 128)
}
}
#[ext(name = UserShapeExt, defunc(via = shape))]
pub impl<This> This
where
This: ShapeAlg + FieldAlg,
{
fn user_shape(&self) {
self.record()
.field(id, self.int(false, 64))
.field(display_name, self.text())
.field(balance, self.amount())
.field(checksum, self.checksum())
}
fn timestamps_shape(&self) {
self.record().field(created_at, self.int(false, 64))
}
fn stored_user_shape(&self) {
self.record().merge(self.user_shape()).merge(self.timestamps_shape())
}
}
#[test]
fn a_declaration_states_a_shape() {
let text = TextShape.compile_shape(TextShape.user_shape());
assert_eq!(text, "user { id: u64, display_name: text, balance: decimal u128, checksum: hex bytes<32> }",);
}
#[test]
fn a_nested_declaration_merges_what_it_names() {
let text = TextShape.compile_shape(TextShape.stored_user_shape());
assert_eq!(
text,
"stored_user { ..user { id: u64, display_name: text, balance: decimal u128, \
checksum: hex bytes<32> }, ..timestamps { created_at: u64 } }",
);
}
#[alux_shape::shape_layout]
#[ext(name = AccountShapeExt, defunc(via = shape))]
pub impl<This> This
where
This: ShapeAlg + FieldAlg,
{
fn account_shape(&self) {
self.record().field::<String>(display_name, self.text()).field::<u64>(created_at, self.int(false, 64))
}
}
#[test]
fn a_declaration_states_its_layout_as_well() {
let account = Account { display_name: "ada".into(), created_at: 1 };
assert_eq!(TextShape.compile_shape(TextShape.account_shape()), "account { display_name: text, created_at: u64 }",);
assert_eq!(account.display_name, "ada");
assert_eq!(
<Account as alux_shape::ShapeOf<TextShape>>::shape_of(&TextShape),
"account { display_name: text, created_at: u64 }",
);
}