use crate::{FieldAlg, ShapeAlg, Words};
use alux_ext::ext;
#[ext(name = ShapeExt)]
pub impl<This> This
where
This: ShapeAlg,
{
fn bytes_hex(&self, len: Option<usize>) -> Self::Ty {
self.hex(self.bytes(len))
}
fn bytes_array(&self) -> Self::Ty {
self.seq(self.int(false, 8))
}
fn int_decimal(&self, signed: bool, bits: u16) -> Self::Ty {
self.decimal(self.int(signed, bits))
}
fn int_hex(&self, signed: bool, bits: u16) -> Self::Ty {
self.hex(self.int(signed, bits))
}
fn named_product(&self, words: Words<'_>, fields: Vec<Self::Field>) -> Self::Ty {
self.named(words, self.product(fields))
}
fn sum_untagged<'w>(&self, alternatives: Vec<(Words<'w>, Self::Ty)>) -> Self::Ty {
self.choice(alternatives.into_iter().map(|(_, shape)| shape).collect())
}
fn sum_of_names<'w>(&self, names: Vec<Words<'w>>) -> Self::Ty {
self.choice(names.into_iter().map(|words| self.name_word(words)).collect())
}
}
#[ext(name = ShapeTaggedExt)]
pub impl<This> This
where
This: ShapeAlg + FieldAlg,
{
fn sum_external<'w>(&self, alternatives: Vec<(Words<'w>, Self::Ty)>) -> Self::Ty {
let alternatives =
alternatives.into_iter().map(|(words, shape)| self.product(vec![self.field(words, shape)])).collect();
self.choice(alternatives)
}
fn sum_internal<'w>(&self, tag: Words<'w>, alternatives: Vec<(Words<'w>, Self::Ty)>) -> Self::Ty {
let alternatives = alternatives
.into_iter()
.map(|(words, shape)| self.product(vec![self.field(tag, self.name_word(words)), self.merge(shape)]))
.collect();
self.choice(alternatives)
}
fn sum_adjacent<'w>(
&self,
tag: Words<'w>,
content: Words<'w>,
alternatives: Vec<(Words<'w>, Self::Ty)>,
) -> Self::Ty {
let alternatives = alternatives
.into_iter()
.map(|(words, shape)| {
self.product(vec![self.field(tag, self.name_word(words)), self.field(content, shape)])
})
.collect();
self.choice(alternatives)
}
}