logic_mesh/base/block/
desc.rs

1// Copyright (c) 2022-2023, Radu Racariu.
2
3//!
4//! Defines the block description
5//!
6
7use std::fmt::Display;
8
9use libhaystack::val::kind::HaystackKind;
10
11use super::BlockProps;
12
13/// Description of a block.
14/// This is a static description of a block,
15/// used to find the block in the library and
16/// inspect its inputs and outputs.
17#[derive(Default, Debug, Clone, PartialEq)]
18pub struct BlockDesc {
19    /// The block name
20    pub name: String,
21    /// The block library
22    pub library: String,
23    /// The block friendly name
24    pub dis: String,
25    /// The block category
26    pub category: String,
27    /// The block version
28    pub ver: String,
29    /// List of the inputs of the block
30    pub inputs: Vec<BlockPin>,
31    /// The outputs of the block
32    pub outputs: Vec<BlockPin>,
33    /// Block documentation
34    pub doc: String,
35    /// Block implementation
36    pub implementation: BlockImplementation,
37
38    /// The condition under which the block should run
39    pub run_condition: Option<BlockRunCondition>,
40}
41
42impl BlockDesc {
43    /// Returns the qualified name of the block
44    pub fn qname(&self) -> String {
45        format!("{}::{}", self.library, self.name)
46    }
47}
48
49/// Trait for providing static access to a block description.
50///
51/// This would complement the instance method access, as the instance
52/// one allows block to be trait objects.
53pub trait BlockStaticDesc: BlockProps {
54    /// Static access to the block description
55    fn desc() -> &'static BlockDesc
56    where
57        Self: Sized;
58}
59
60/// Defines a block pin
61///
62/// A block pin is either an input or an output
63#[derive(Default, Debug, Clone, PartialEq)]
64pub struct BlockPin {
65    pub name: String,
66    pub kind: HaystackKind,
67}
68
69/// Defines the block implementation
70#[derive(Default, Debug, Clone, PartialEq)]
71pub enum BlockImplementation {
72    /// A block that is implemented in Rust
73    #[default]
74    Native,
75    /// A block that is implemented over a FFI interface, such as JavaScript
76    External,
77}
78
79impl TryFrom<&str> for BlockImplementation {
80    type Error = String;
81
82    fn try_from(implementation: &str) -> Result<Self, Self::Error> {
83        match implementation {
84            "native" => Ok(BlockImplementation::Native),
85            "external" => Ok(BlockImplementation::External),
86            _ => Err(format!("Invalid implementation: {implementation}")),
87        }
88    }
89}
90
91impl Display for BlockImplementation {
92    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        let kind = match self {
94            BlockImplementation::Native => "native",
95            BlockImplementation::External => "external",
96        };
97        write!(fmt, "{kind}")
98    }
99}
100
101/// Defines the block implementation
102#[derive(Default, Debug, Clone, PartialEq)]
103pub enum BlockRunCondition {
104    /// Runs on change of inputs
105    #[default]
106    Change,
107    /// Always runs, regardless of inputs
108    Always,
109}
110
111impl TryFrom<&str> for BlockRunCondition {
112    type Error = String;
113
114    fn try_from(implementation: &str) -> Result<Self, Self::Error> {
115        match implementation {
116            "change" => Ok(BlockRunCondition::Change),
117            "always" => Ok(BlockRunCondition::Always),
118            _ => Err(format!("Invalid implementation: {implementation}")),
119        }
120    }
121}
122
123impl Display for BlockRunCondition {
124    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125        let kind = match self {
126            BlockRunCondition::Change => "native",
127            BlockRunCondition::Always => "external",
128        };
129        write!(fmt, "{kind}")
130    }
131}