use toasty::stmt::Path;
pub struct Lens<M, T> {
path: Path<M, T>,
read: fn(&M) -> &T,
}
impl<M, T> Lens<M, T> {
#[doc(hidden)]
pub fn new(path: Path<M, T>, read: fn(&M) -> &T) -> Self {
Self { path, read }
}
pub fn path(&self) -> &Path<M, T> {
&self.path
}
pub fn read<'a>(&self, record: &'a M) -> &'a T {
(self.read)(record)
}
}
impl<M, T> Clone for Lens<M, T> {
fn clone(&self) -> Self {
Self {
path: self.path.clone(),
read: self.read,
}
}
}
impl<M, T> std::fmt::Debug for Lens<M, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Lens").field(&self.path).finish()
}
}
impl<M, T> From<Lens<M, T>> for Path<M, T> {
fn from(lens: Lens<M, T>) -> Self {
lens.path
}
}
#[macro_export]
macro_rules! lens {
($($model:ident)::+ . $($field:ident).+) => {
$crate::Lens::new(
<$($model)::+>::fields()$(.$field())+,
|record: &$($model)::+| &record$(.$field)+,
)
};
}
#[cfg(test)]
mod tests;