1use std::cell::RefCell;
23use std::hash::Hash;
24use std::rc::Rc;
25
26pub type Nat = u64;
28pub type Int = i64;
30pub type Real = f64;
32pub type Text = String;
34pub type Bool = bool;
36pub type Unit = ();
38pub type Char = char;
40pub type Byte = u8;
42
43#[derive(Debug)]
49pub struct LogosSeq<T>(pub Rc<RefCell<Vec<T>>>);
50
51impl<T> LogosSeq<T> {
52 pub fn new() -> Self {
53 Self(Rc::new(RefCell::new(Vec::new())))
54 }
55
56 pub fn from_vec(v: Vec<T>) -> Self {
57 Self(Rc::new(RefCell::new(v)))
58 }
59
60 pub fn with_capacity(cap: usize) -> Self {
61 Self(Rc::new(RefCell::new(Vec::with_capacity(cap))))
62 }
63
64 pub fn push(&self, value: T) {
65 self.0.borrow_mut().push(value);
66 }
67
68 pub fn pop(&self) -> Option<T> {
69 self.0.borrow_mut().pop()
70 }
71
72 pub fn len(&self) -> usize {
73 self.0.borrow().len()
74 }
75
76 pub fn is_empty(&self) -> bool {
77 self.0.borrow().is_empty()
78 }
79
80 pub fn remove(&self, index: usize) -> T {
81 self.0.borrow_mut().remove(index)
82 }
83
84 pub fn borrow(&self) -> std::cell::Ref<'_, Vec<T>> {
85 self.0.borrow()
86 }
87
88 pub fn borrow_mut(&self) -> std::cell::RefMut<'_, Vec<T>> {
89 self.0.borrow_mut()
90 }
91}
92
93impl<T: Clone> LogosSeq<T> {
94 pub fn deep_clone(&self) -> Self {
95 Self(Rc::new(RefCell::new(self.0.borrow().clone())))
96 }
97
98 pub fn to_vec(&self) -> Vec<T> {
99 self.0.borrow().clone()
100 }
101
102 pub fn extend_from_slice(&self, other: &[T]) {
103 self.0.borrow_mut().extend_from_slice(other);
104 }
105
106 pub fn iter(&self) -> LogosSeqIter<T> {
107 LogosSeqIter {
108 data: self.to_vec(),
109 pos: 0,
110 }
111 }
112}
113
114pub struct LogosSeqIter<T> {
115 data: Vec<T>,
116 pos: usize,
117}
118
119impl<T: Clone> Iterator for LogosSeqIter<T> {
120 type Item = T;
121 fn next(&mut self) -> Option<T> {
122 if self.pos < self.data.len() {
123 let val = self.data[self.pos].clone();
124 self.pos += 1;
125 Some(val)
126 } else {
127 None
128 }
129 }
130}
131
132impl<T: Ord> LogosSeq<T> {
133 pub fn sort(&self) {
134 self.0.borrow_mut().sort();
135 }
136}
137
138impl<T> LogosSeq<T> {
139 pub fn reverse(&self) {
140 self.0.borrow_mut().reverse();
141 }
142}
143
144impl<T> Clone for LogosSeq<T> {
145 fn clone(&self) -> Self {
146 Self(Rc::clone(&self.0))
147 }
148}
149
150impl<T> Default for LogosSeq<T> {
151 fn default() -> Self {
152 Self::new()
153 }
154}
155
156impl<T: PartialEq> PartialEq for LogosSeq<T> {
157 fn eq(&self, other: &Self) -> bool {
158 *self.0.borrow() == *other.0.borrow()
159 }
160}
161
162impl<T: std::fmt::Display> std::fmt::Display for LogosSeq<T> {
163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 let inner = self.0.borrow();
165 write!(f, "[")?;
166 for (i, item) in inner.iter().enumerate() {
167 if i > 0 { write!(f, ", ")?; }
168 write!(f, "{}", item)?;
169 }
170 write!(f, "]")
171 }
172}
173
174impl<T> From<Vec<T>> for LogosSeq<T> {
175 fn from(v: Vec<T>) -> Self {
176 Self::from_vec(v)
177 }
178}
179
180impl<T: serde::Serialize> serde::Serialize for LogosSeq<T> {
181 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
182 self.0.borrow().serialize(serializer)
183 }
184}
185
186impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for LogosSeq<T> {
187 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
188 let vec = Vec::<T>::deserialize(deserializer)?;
189 Ok(Self::from_vec(vec))
190 }
191}
192
193impl<T: PartialEq> LogosContains<T> for LogosSeq<T> {
194 #[inline(always)]
195 fn logos_contains(&self, value: &T) -> bool {
196 self.0.borrow().contains(value)
197 }
198}
199
200impl<T: Clone> IntoIterator for LogosSeq<T> {
201 type Item = T;
202 type IntoIter = std::vec::IntoIter<T>;
203
204 fn into_iter(self) -> Self::IntoIter {
205 self.to_vec().into_iter()
206 }
207}
208
209#[derive(Debug)]
215pub struct LogosMap<K, V>(pub Rc<RefCell<rustc_hash::FxHashMap<K, V>>>);
216
217impl<K: Eq + Hash, V> LogosMap<K, V> {
218 pub fn new() -> Self {
219 Self(Rc::new(RefCell::new(rustc_hash::FxHashMap::default())))
220 }
221
222 pub fn with_capacity(cap: usize) -> Self {
223 Self(Rc::new(RefCell::new(
224 rustc_hash::FxHashMap::with_capacity_and_hasher(cap, Default::default()),
225 )))
226 }
227
228 pub fn from_map(m: rustc_hash::FxHashMap<K, V>) -> Self {
229 Self(Rc::new(RefCell::new(m)))
230 }
231
232 pub fn insert(&self, key: K, value: V) -> Option<V> {
233 self.0.borrow_mut().insert(key, value)
234 }
235
236 pub fn remove(&self, key: &K) -> Option<V> {
237 self.0.borrow_mut().remove(key)
238 }
239
240 pub fn len(&self) -> usize {
241 self.0.borrow().len()
242 }
243
244 pub fn is_empty(&self) -> bool {
245 self.0.borrow().is_empty()
246 }
247
248 pub fn contains_key(&self, key: &K) -> bool {
249 self.0.borrow().contains_key(key)
250 }
251
252 pub fn borrow(&self) -> std::cell::Ref<'_, rustc_hash::FxHashMap<K, V>> {
253 self.0.borrow()
254 }
255
256 pub fn borrow_mut(&self) -> std::cell::RefMut<'_, rustc_hash::FxHashMap<K, V>> {
257 self.0.borrow_mut()
258 }
259}
260
261impl<K: Eq + Hash + Clone, V: Clone> LogosMap<K, V> {
262 pub fn deep_clone(&self) -> Self {
263 Self(Rc::new(RefCell::new(self.0.borrow().clone())))
264 }
265
266 pub fn get(&self, key: &K) -> Option<V> {
267 self.0.borrow().get(key).cloned()
268 }
269
270 pub fn values(&self) -> Vec<V> {
271 self.0.borrow().values().cloned().collect()
272 }
273
274 pub fn keys(&self) -> Vec<K> {
275 self.0.borrow().keys().cloned().collect()
276 }
277}
278
279impl<K, V> Clone for LogosMap<K, V> {
280 fn clone(&self) -> Self {
281 Self(Rc::clone(&self.0))
282 }
283}
284
285impl<K: Eq + Hash, V> Default for LogosMap<K, V> {
286 fn default() -> Self {
287 Self::new()
288 }
289}
290
291impl<K: PartialEq + Eq + Hash, V: PartialEq> PartialEq for LogosMap<K, V> {
292 fn eq(&self, other: &Self) -> bool {
293 *self.0.borrow() == *other.0.borrow()
294 }
295}
296
297impl<K: std::fmt::Display + Eq + Hash, V: std::fmt::Display> std::fmt::Display for LogosMap<K, V> {
298 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
299 let inner = self.0.borrow();
300 write!(f, "{{")?;
301 for (i, (k, v)) in inner.iter().enumerate() {
302 if i > 0 { write!(f, ", ")?; }
303 write!(f, "{}: {}", k, v)?;
304 }
305 write!(f, "}}")
306 }
307}
308
309impl<K: serde::Serialize + Eq + Hash, V: serde::Serialize> serde::Serialize for LogosMap<K, V> {
310 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
311 self.0.borrow().serialize(serializer)
312 }
313}
314
315impl<'de, K: serde::Deserialize<'de> + Eq + Hash, V: serde::Deserialize<'de>> serde::Deserialize<'de> for LogosMap<K, V> {
316 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
317 let map = rustc_hash::FxHashMap::<K, V>::deserialize(deserializer)?;
318 Ok(Self::from_map(map))
319 }
320}
321
322impl<K: Eq + Hash, V> LogosContains<K> for LogosMap<K, V> {
323 #[inline(always)]
324 fn logos_contains(&self, key: &K) -> bool {
325 self.0.borrow().contains_key(key)
326 }
327}
328
329pub type Seq<T> = LogosSeq<T>;
331
332pub type Map<K, V> = LogosMap<K, V>;
334
335pub type Set<T> = rustc_hash::FxHashSet<T>;
337
338pub trait LogosContains<T> {
371 fn logos_contains(&self, value: &T) -> bool;
373}
374
375impl<T: PartialEq> LogosContains<T> for Vec<T> {
376 #[inline(always)]
377 fn logos_contains(&self, value: &T) -> bool {
378 self.contains(value)
379 }
380}
381
382impl<T: PartialEq> LogosContains<T> for [T] {
383 #[inline(always)]
384 fn logos_contains(&self, value: &T) -> bool {
385 self.contains(value)
386 }
387}
388
389impl<T: Eq + Hash> LogosContains<T> for rustc_hash::FxHashSet<T> {
390 #[inline(always)]
391 fn logos_contains(&self, value: &T) -> bool {
392 self.contains(value)
393 }
394}
395
396impl<K: Eq + Hash, V> LogosContains<K> for rustc_hash::FxHashMap<K, V> {
397 #[inline(always)]
398 fn logos_contains(&self, key: &K) -> bool {
399 self.contains_key(key)
400 }
401}
402
403impl LogosContains<&str> for String {
404 #[inline(always)]
405 fn logos_contains(&self, value: &&str) -> bool {
406 self.contains(*value)
407 }
408}
409
410impl LogosContains<String> for String {
411 #[inline(always)]
412 fn logos_contains(&self, value: &String) -> bool {
413 self.contains(value.as_str())
414 }
415}
416
417impl LogosContains<char> for String {
418 #[inline(always)]
419 fn logos_contains(&self, value: &char) -> bool {
420 self.contains(*value)
421 }
422}
423
424impl<T: Eq + Hash + Clone, B: crate::crdt::SetBias> LogosContains<T>
425 for crate::crdt::ORSet<T, B>
426{
427 #[inline(always)]
428 fn logos_contains(&self, value: &T) -> bool {
429 self.contains(value)
430 }
431}
432
433#[derive(Clone, Debug, PartialEq)]
474pub enum Value {
475 Int(i64),
477 Float(f64),
479 Bool(bool),
481 Text(String),
483 Char(char),
485 Nothing,
487}
488
489impl std::fmt::Display for Value {
490 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
491 match self {
492 Value::Int(n) => write!(f, "{}", n),
493 Value::Float(n) => write!(f, "{}", n),
494 Value::Bool(b) => write!(f, "{}", b),
495 Value::Text(s) => write!(f, "{}", s),
496 Value::Char(c) => write!(f, "{}", c),
497 Value::Nothing => write!(f, "nothing"),
498 }
499 }
500}
501
502impl From<i64> for Value {
504 fn from(n: i64) -> Self { Value::Int(n) }
505}
506
507impl From<f64> for Value {
508 fn from(n: f64) -> Self { Value::Float(n) }
509}
510
511impl From<bool> for Value {
512 fn from(b: bool) -> Self { Value::Bool(b) }
513}
514
515impl From<String> for Value {
516 fn from(s: String) -> Self { Value::Text(s) }
517}
518
519impl From<&str> for Value {
520 fn from(s: &str) -> Self { Value::Text(s.to_string()) }
521}
522
523impl From<char> for Value {
524 fn from(c: char) -> Self { Value::Char(c) }
525}
526
527pub type Tuple = Vec<Value>;
529
530impl std::ops::Add for Value {
535 type Output = Value;
536
537 #[inline]
538 fn add(self, other: Value) -> Value {
539 match (self, other) {
540 (Value::Int(a), Value::Int(b)) => Value::Int(a + b),
541 (Value::Float(a), Value::Float(b)) => Value::Float(a + b),
542 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 + b),
543 (Value::Float(a), Value::Int(b)) => Value::Float(a + b as f64),
544 (Value::Text(a), Value::Text(b)) => Value::Text(format!("{}{}", a, b)),
545 _ => panic!("Cannot add these value types"),
546 }
547 }
548}
549
550impl std::ops::Sub for Value {
551 type Output = Value;
552
553 #[inline]
554 fn sub(self, other: Value) -> Value {
555 match (self, other) {
556 (Value::Int(a), Value::Int(b)) => Value::Int(a - b),
557 (Value::Float(a), Value::Float(b)) => Value::Float(a - b),
558 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 - b),
559 (Value::Float(a), Value::Int(b)) => Value::Float(a - b as f64),
560 _ => panic!("Cannot subtract these value types"),
561 }
562 }
563}
564
565impl std::ops::Mul for Value {
566 type Output = Value;
567
568 #[inline]
569 fn mul(self, other: Value) -> Value {
570 match (self, other) {
571 (Value::Int(a), Value::Int(b)) => Value::Int(a * b),
572 (Value::Float(a), Value::Float(b)) => Value::Float(a * b),
573 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 * b),
574 (Value::Float(a), Value::Int(b)) => Value::Float(a * b as f64),
575 _ => panic!("Cannot multiply these value types"),
576 }
577 }
578}
579
580impl std::ops::Div for Value {
581 type Output = Value;
582
583 #[inline]
584 fn div(self, other: Value) -> Value {
585 match (self, other) {
586 (Value::Int(a), Value::Int(b)) => Value::Int(a / b),
587 (Value::Float(a), Value::Float(b)) => Value::Float(a / b),
588 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 / b),
589 (Value::Float(a), Value::Int(b)) => Value::Float(a / b as f64),
590 _ => panic!("Cannot divide these value types"),
591 }
592 }
593}
594
595#[cfg(test)]
596mod tests {
597 use super::*;
598
599 #[test]
600 fn value_int_arithmetic() {
601 assert_eq!(Value::Int(10) + Value::Int(3), Value::Int(13));
602 assert_eq!(Value::Int(10) - Value::Int(3), Value::Int(7));
603 assert_eq!(Value::Int(10) * Value::Int(3), Value::Int(30));
604 assert_eq!(Value::Int(10) / Value::Int(3), Value::Int(3));
605 }
606
607 #[test]
608 fn value_float_arithmetic() {
609 assert_eq!(Value::Float(2.5) + Value::Float(1.5), Value::Float(4.0));
610 assert_eq!(Value::Float(5.0) - Value::Float(1.5), Value::Float(3.5));
611 assert_eq!(Value::Float(2.0) * Value::Float(3.0), Value::Float(6.0));
612 assert_eq!(Value::Float(7.0) / Value::Float(2.0), Value::Float(3.5));
613 }
614
615 #[test]
616 fn value_cross_type_promotion() {
617 assert_eq!(Value::Int(2) + Value::Float(1.5), Value::Float(3.5));
618 assert_eq!(Value::Float(2.5) + Value::Int(2), Value::Float(4.5));
619 assert_eq!(Value::Int(3) * Value::Float(2.0), Value::Float(6.0));
620 assert_eq!(Value::Float(6.0) / Value::Int(2), Value::Float(3.0));
621 }
622
623 #[test]
624 fn value_text_concat() {
625 assert_eq!(
626 Value::Text("hello".to_string()) + Value::Text(" world".to_string()),
627 Value::Text("hello world".to_string())
628 );
629 }
630
631 #[test]
632 #[should_panic(expected = "divide by zero")]
633 fn value_div_by_zero_panics() {
634 let _ = Value::Int(1) / Value::Int(0);
635 }
636
637 #[test]
638 #[should_panic(expected = "Cannot add")]
639 fn value_incompatible_types_panic() {
640 let _ = Value::Bool(true) + Value::Int(1);
641 }
642
643 #[test]
644 fn value_display() {
645 assert_eq!(format!("{}", Value::Int(42)), "42");
646 assert_eq!(format!("{}", Value::Float(3.14)), "3.14");
647 assert_eq!(format!("{}", Value::Bool(true)), "true");
648 assert_eq!(format!("{}", Value::Text("hi".to_string())), "hi");
649 assert_eq!(format!("{}", Value::Char('a')), "a");
650 assert_eq!(format!("{}", Value::Nothing), "nothing");
651 }
652
653 #[test]
654 fn value_from_conversions() {
655 assert_eq!(Value::from(42i64), Value::Int(42));
656 assert_eq!(Value::from(3.14f64), Value::Float(3.14));
657 assert_eq!(Value::from(true), Value::Bool(true));
658 assert_eq!(Value::from("hello"), Value::Text("hello".to_string()));
659 assert_eq!(Value::from("hello".to_string()), Value::Text("hello".to_string()));
660 assert_eq!(Value::from('x'), Value::Char('x'));
661 }
662}