use std::sync::Arc;
use sim_kernel::{CapabilityName, Cx, Diagnostic, Expr, Result, ShapeRef, Symbol};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LensKind {
View,
Editor,
Inspector,
Overlay,
Action,
}
#[derive(Clone)]
pub struct LensMeta {
pub id: Symbol,
pub kind: LensKind,
pub claimed_shapes: Vec<ShapeRef>,
pub claimed_classes: Vec<Symbol>,
pub quality: i32,
pub cost: i32,
pub required_capabilities: Vec<CapabilityName>,
pub preferred_modes: Vec<Symbol>,
pub universal_default: bool,
}
impl LensMeta {
pub fn new(id: Symbol, kind: LensKind) -> Self {
Self {
id,
kind,
claimed_shapes: Vec::new(),
claimed_classes: Vec::new(),
quality: 0,
cost: 0,
required_capabilities: Vec::new(),
preferred_modes: Vec::new(),
universal_default: false,
}
}
pub fn claiming_shape(mut self, shape: ShapeRef) -> Self {
self.claimed_shapes.push(shape);
self
}
pub fn claiming_class(mut self, class: Symbol) -> Self {
self.claimed_classes.push(class);
self
}
pub fn with_quality_cost(mut self, quality: i32, cost: i32) -> Self {
self.quality = quality;
self.cost = cost;
self
}
pub fn requiring(mut self, capability: CapabilityName) -> Self {
self.required_capabilities.push(capability);
self
}
pub fn preferring_mode(mut self, mode: Symbol) -> Self {
self.preferred_modes.push(mode);
self
}
pub fn as_universal_default(mut self) -> Self {
self.universal_default = true;
self
}
}
pub trait View: Send + Sync {
fn encode(&self, cx: &mut Cx, value: &Expr) -> Result<Expr>;
}
pub trait Editor: Send + Sync {
fn decode(&self, cx: &mut Cx, value: &Expr, intent: &Expr) -> Result<Draft>;
fn commit(&self, cx: &mut Cx, draft: &Draft) -> Result<Operation>;
}
#[derive(Clone, Debug)]
pub struct Draft {
pub base: Expr,
pub proposed: Expr,
pub committable: bool,
pub diagnostics: Vec<Diagnostic>,
}
impl Draft {
pub fn clean(base: Expr, proposed: Expr) -> Self {
Self {
base,
proposed,
committable: true,
diagnostics: Vec::new(),
}
}
pub fn rejected(base: Expr, diagnostic: Diagnostic) -> Self {
Self {
proposed: base.clone(),
base,
committable: false,
diagnostics: vec![diagnostic],
}
}
}
#[derive(Clone, Debug)]
pub struct Operation {
pub form: Expr,
}
#[derive(Clone)]
pub struct Lens {
pub meta: LensMeta,
pub view: Option<Arc<dyn View>>,
pub editor: Option<Arc<dyn Editor>>,
}
impl Lens {
pub fn metadata_only(meta: LensMeta) -> Self {
Self {
meta,
view: None,
editor: None,
}
}
pub fn view(meta: LensMeta, view: Arc<dyn View>) -> Self {
Self {
meta,
view: Some(view),
editor: None,
}
}
pub fn editor(meta: LensMeta, editor: Arc<dyn Editor>) -> Self {
Self {
meta,
view: None,
editor: Some(editor),
}
}
}