1use std::collections::HashMap;
4use std::hash::Hash;
5use std::sync::Arc;
6
7use all_the_same::all_the_same;
8use derive_more::From;
9use ustr::Ustr;
10
11use serde::{Deserialize, Serialize};
12use tsify_next::Tsify;
13use wasm_bindgen::prelude::*;
14
15use catlog::dbl::theory;
16use catlog::dbl::theory::{DblTheory as _, TabMorType, TabObType};
17use catlog::one::fin_category::*;
18
19#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Tsify)]
21#[serde(tag = "tag", content = "content")]
22#[tsify(into_wasm_abi, from_wasm_abi)]
23pub enum ObType {
24 Basic(Ustr),
26
27 Tabulator(Box<MorType>),
29}
30
31#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, Tsify)]
33#[serde(tag = "tag", content = "content")]
34#[tsify(into_wasm_abi, from_wasm_abi)]
35pub enum MorType {
36 Basic(Ustr),
38
39 Hom(Box<ObType>),
41}
42
43impl From<Ustr> for ObType {
45 fn from(value: Ustr) -> Self {
46 ObType::Basic(value)
47 }
48}
49
50impl From<FinMor<Ustr, Ustr>> for MorType {
52 fn from(mor: FinMor<Ustr, Ustr>) -> Self {
53 match mor {
54 FinMor::Generator(e) => MorType::Basic(e),
55 FinMor::Id(v) => MorType::Hom(Box::new(ObType::Basic(v))),
56 }
57 }
58}
59
60impl TryFrom<ObType> for Ustr {
62 type Error = String;
63
64 fn try_from(ob_type: ObType) -> Result<Self, Self::Error> {
65 match ob_type {
66 ObType::Basic(name) => Ok(name),
67 _ => Err(format!("Cannot cast object type for discrete double theory: {:#?}", ob_type)),
68 }
69 }
70}
71
72impl TryFrom<MorType> for FinMor<Ustr, Ustr> {
74 type Error = String;
75
76 fn try_from(mor_type: MorType) -> Result<Self, Self::Error> {
77 match mor_type {
78 MorType::Basic(name) => Ok(FinMor::Generator(name)),
79 MorType::Hom(x) => (*x).try_into().map(FinMor::Id),
80 }
81 }
82}
83
84impl From<TabObType<Ustr, Ustr>> for ObType {
86 fn from(ob_type: TabObType<Ustr, Ustr>) -> Self {
87 match ob_type {
88 TabObType::Basic(name) => ObType::Basic(name),
89 TabObType::Tabulator(m) => ObType::Tabulator(Box::new((*m).into())),
90 }
91 }
92}
93
94impl From<TabMorType<Ustr, Ustr>> for MorType {
96 fn from(mor_type: TabMorType<Ustr, Ustr>) -> Self {
97 match mor_type {
98 TabMorType::Basic(name) => MorType::Basic(name),
99 TabMorType::Hom(x) => MorType::Hom(Box::new((*x).into())),
100 }
101 }
102}
103
104impl TryFrom<ObType> for TabObType<Ustr, Ustr> {
106 type Error = String;
107
108 fn try_from(ob_type: ObType) -> Result<Self, Self::Error> {
109 match ob_type {
110 ObType::Basic(name) => Ok(TabObType::Basic(name)),
111 ObType::Tabulator(m) => (*m).try_into().map(|m| TabObType::Tabulator(Box::new(m))),
112 }
113 }
114}
115
116impl TryFrom<MorType> for TabMorType<Ustr, Ustr> {
118 type Error = String;
119
120 fn try_from(mor_type: MorType) -> Result<Self, Self::Error> {
121 match mor_type {
122 MorType::Basic(name) => Ok(TabMorType::Basic(name)),
123 MorType::Hom(x) => (*x).try_into().map(|x| TabMorType::Hom(Box::new(x))),
124 }
125 }
126}
127
128#[derive(From)]
136pub enum DblTheoryBox {
137 Discrete(Arc<theory::UstrDiscreteDblTheory>),
138 DiscreteTab(Arc<theory::UstrDiscreteTabTheory>),
139}
140
141#[wasm_bindgen]
144pub struct DblTheory(#[wasm_bindgen(skip)] pub DblTheoryBox);
145
146#[wasm_bindgen]
147impl DblTheory {
148 #[wasm_bindgen(getter)]
150 pub fn kind(&self) -> String {
151 match &self.0 {
153 DblTheoryBox::Discrete(_) => "Discrete",
154 DblTheoryBox::DiscreteTab(_) => "DiscreteTab",
155 }
156 .into()
157 }
158
159 #[wasm_bindgen]
161 pub fn src(&self, mor_type: MorType) -> Result<ObType, String> {
162 all_the_same!(match &self.0 {
163 DblTheoryBox::[Discrete, DiscreteTab](th) => {
164 let m = mor_type.try_into()?;
165 Ok(th.src_type(&m).into())
166 }
167 })
168 }
169
170 #[wasm_bindgen]
172 pub fn tgt(&self, mor_type: MorType) -> Result<ObType, String> {
173 all_the_same!(match &self.0 {
174 DblTheoryBox::[Discrete, DiscreteTab](th) => {
175 let m = mor_type.try_into()?;
176 Ok(th.tgt_type(&m).into())
177 }
178 })
179 }
180}
181
182#[wasm_bindgen]
188#[derive(Clone, Default)]
189pub struct ObTypeIndex(HashMap<ObType, usize>);
190
191#[wasm_bindgen]
192impl ObTypeIndex {
193 #[wasm_bindgen(constructor)]
195 pub fn new() -> Self {
196 Default::default()
197 }
198
199 #[wasm_bindgen]
201 pub fn get(&self, x: &ObType) -> Option<usize> {
202 self.0.get(x).copied()
203 }
204
205 #[wasm_bindgen]
207 pub fn set(&mut self, x: ObType, i: usize) {
208 self.0.insert(x, i);
209 }
210}
211
212#[wasm_bindgen]
218#[derive(Clone, Default)]
219pub struct MorTypeIndex(HashMap<MorType, usize>);
220
221#[wasm_bindgen]
222impl MorTypeIndex {
223 #[wasm_bindgen(constructor)]
225 pub fn new() -> Self {
226 Default::default()
227 }
228
229 #[wasm_bindgen]
231 pub fn get(&self, m: &MorType) -> Option<usize> {
232 self.0.get(m).copied()
233 }
234
235 #[wasm_bindgen]
237 pub fn set(&mut self, m: MorType, i: usize) {
238 self.0.insert(m, i);
239 }
240}