use crate::namespace::Namespace;
use nebu::Goldilocks;
pub trait EvyComponent: Sized {
const NAMESPACE: Namespace;
fn to_goldilocks(&self) -> Vec<Goldilocks>;
fn from_goldilocks(slice: &[Goldilocks]) -> Self;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::codec::GoldilocksCodec;
#[derive(Debug, Clone, Copy, PartialEq)]
struct Position {
x: f32,
y: f32,
z: f32,
}
impl EvyComponent for Position {
const NAMESPACE: Namespace = Namespace::Ephemeral;
fn to_goldilocks(&self) -> Vec<Goldilocks> {
let mut v = Vec::with_capacity(3);
self.x.encode_into(&mut v);
self.y.encode_into(&mut v);
self.z.encode_into(&mut v);
v
}
fn from_goldilocks(slice: &[Goldilocks]) -> Self {
Self {
x: f32::decode_from(&slice[0..1]),
y: f32::decode_from(&slice[1..2]),
z: f32::decode_from(&slice[2..3]),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
struct Balance(u64);
impl EvyComponent for Balance {
const NAMESPACE: Namespace = Namespace::Coins;
fn to_goldilocks(&self) -> Vec<Goldilocks> {
self.0.encode()
}
fn from_goldilocks(slice: &[Goldilocks]) -> Self {
Self(u64::decode_from(slice))
}
}
#[test]
fn position_round_trip() {
let p = Position {
x: 1.0,
y: 2.0,
z: 3.0,
};
let enc = p.to_goldilocks();
assert_eq!(enc.len(), 3);
let dec = Position::from_goldilocks(&enc);
assert_eq!(dec, p);
}
#[test]
fn balance_round_trip() {
let b = Balance(1_000_000);
let enc = b.to_goldilocks();
assert_eq!(enc.len(), 1);
let dec = Balance::from_goldilocks(&enc);
assert_eq!(dec, b);
}
#[test]
fn namespaces_match() {
assert_eq!(Position::NAMESPACE, Namespace::Ephemeral);
assert!(!Position::NAMESPACE.is_authenticated());
assert_eq!(Balance::NAMESPACE, Namespace::Coins);
assert!(Balance::NAMESPACE.is_authenticated());
}
}