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: PartialEq> LogosContains<T> for LogosSeq<T> {
181 #[inline(always)]
182 fn logos_contains(&self, value: &T) -> bool {
183 self.0.borrow().contains(value)
184 }
185}
186
187impl<T: Clone> IntoIterator for LogosSeq<T> {
188 type Item = T;
189 type IntoIter = std::vec::IntoIter<T>;
190
191 fn into_iter(self) -> Self::IntoIter {
192 self.to_vec().into_iter()
193 }
194}
195
196#[derive(Debug)]
202pub struct LogosMap<K, V>(pub Rc<RefCell<rustc_hash::FxHashMap<K, V>>>);
203
204impl<K: Eq + Hash, V> LogosMap<K, V> {
205 pub fn new() -> Self {
206 Self(Rc::new(RefCell::new(rustc_hash::FxHashMap::default())))
207 }
208
209 pub fn with_capacity(cap: usize) -> Self {
210 Self(Rc::new(RefCell::new(
211 rustc_hash::FxHashMap::with_capacity_and_hasher(cap, Default::default()),
212 )))
213 }
214
215 pub fn from_map(m: rustc_hash::FxHashMap<K, V>) -> Self {
216 Self(Rc::new(RefCell::new(m)))
217 }
218
219 pub fn insert(&self, key: K, value: V) -> Option<V> {
220 self.0.borrow_mut().insert(key, value)
221 }
222
223 pub fn remove(&self, key: &K) -> Option<V> {
224 self.0.borrow_mut().remove(key)
225 }
226
227 pub fn len(&self) -> usize {
228 self.0.borrow().len()
229 }
230
231 pub fn is_empty(&self) -> bool {
232 self.0.borrow().is_empty()
233 }
234
235 pub fn contains_key(&self, key: &K) -> bool {
236 self.0.borrow().contains_key(key)
237 }
238
239 pub fn borrow(&self) -> std::cell::Ref<'_, rustc_hash::FxHashMap<K, V>> {
240 self.0.borrow()
241 }
242
243 pub fn borrow_mut(&self) -> std::cell::RefMut<'_, rustc_hash::FxHashMap<K, V>> {
244 self.0.borrow_mut()
245 }
246}
247
248impl<K: Eq + Hash + Clone, V: Clone> LogosMap<K, V> {
249 pub fn deep_clone(&self) -> Self {
250 Self(Rc::new(RefCell::new(self.0.borrow().clone())))
251 }
252
253 pub fn get(&self, key: &K) -> Option<V> {
254 self.0.borrow().get(key).cloned()
255 }
256
257 pub fn values(&self) -> Vec<V> {
258 self.0.borrow().values().cloned().collect()
259 }
260
261 pub fn keys(&self) -> Vec<K> {
262 self.0.borrow().keys().cloned().collect()
263 }
264}
265
266impl<K, V> Clone for LogosMap<K, V> {
267 fn clone(&self) -> Self {
268 Self(Rc::clone(&self.0))
269 }
270}
271
272impl<K: Eq + Hash, V> Default for LogosMap<K, V> {
273 fn default() -> Self {
274 Self::new()
275 }
276}
277
278impl<K: PartialEq + Eq + Hash, V: PartialEq> PartialEq for LogosMap<K, V> {
279 fn eq(&self, other: &Self) -> bool {
280 *self.0.borrow() == *other.0.borrow()
281 }
282}
283
284impl<K: std::fmt::Display + Eq + Hash, V: std::fmt::Display> std::fmt::Display for LogosMap<K, V> {
285 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 let inner = self.0.borrow();
287 write!(f, "{{")?;
288 for (i, (k, v)) in inner.iter().enumerate() {
289 if i > 0 { write!(f, ", ")?; }
290 write!(f, "{}: {}", k, v)?;
291 }
292 write!(f, "}}")
293 }
294}
295
296impl<K: Eq + Hash, V> LogosContains<K> for LogosMap<K, V> {
297 #[inline(always)]
298 fn logos_contains(&self, key: &K) -> bool {
299 self.0.borrow().contains_key(key)
300 }
301}
302
303pub type Seq<T> = LogosSeq<T>;
305
306pub type Map<K, V> = LogosMap<K, V>;
308
309pub type Set<T> = rustc_hash::FxHashSet<T>;
311
312pub trait LogosContains<T> {
345 fn logos_contains(&self, value: &T) -> bool;
347}
348
349impl<T: PartialEq> LogosContains<T> for Vec<T> {
350 #[inline(always)]
351 fn logos_contains(&self, value: &T) -> bool {
352 self.contains(value)
353 }
354}
355
356impl<T: PartialEq> LogosContains<T> for [T] {
357 #[inline(always)]
358 fn logos_contains(&self, value: &T) -> bool {
359 self.contains(value)
360 }
361}
362
363impl<T: Eq + Hash> LogosContains<T> for rustc_hash::FxHashSet<T> {
364 #[inline(always)]
365 fn logos_contains(&self, value: &T) -> bool {
366 self.contains(value)
367 }
368}
369
370impl<K: Eq + Hash, V> LogosContains<K> for rustc_hash::FxHashMap<K, V> {
371 #[inline(always)]
372 fn logos_contains(&self, key: &K) -> bool {
373 self.contains_key(key)
374 }
375}
376
377impl LogosContains<&str> for String {
378 #[inline(always)]
379 fn logos_contains(&self, value: &&str) -> bool {
380 self.contains(*value)
381 }
382}
383
384impl LogosContains<String> for String {
385 #[inline(always)]
386 fn logos_contains(&self, value: &String) -> bool {
387 self.contains(value.as_str())
388 }
389}
390
391impl LogosContains<char> for String {
392 #[inline(always)]
393 fn logos_contains(&self, value: &char) -> bool {
394 self.contains(*value)
395 }
396}
397
398impl<T: Eq + Hash + Clone, B: crate::crdt::SetBias> LogosContains<T>
399 for crate::crdt::ORSet<T, B>
400{
401 #[inline(always)]
402 fn logos_contains(&self, value: &T) -> bool {
403 self.contains(value)
404 }
405}
406
407#[derive(Clone, Debug, PartialEq)]
448pub enum Value {
449 Int(i64),
451 Float(f64),
453 Bool(bool),
455 Text(String),
457 Char(char),
459 Nothing,
461}
462
463impl std::fmt::Display for Value {
464 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
465 match self {
466 Value::Int(n) => write!(f, "{}", n),
467 Value::Float(n) => write!(f, "{}", n),
468 Value::Bool(b) => write!(f, "{}", b),
469 Value::Text(s) => write!(f, "{}", s),
470 Value::Char(c) => write!(f, "{}", c),
471 Value::Nothing => write!(f, "nothing"),
472 }
473 }
474}
475
476impl From<i64> for Value {
478 fn from(n: i64) -> Self { Value::Int(n) }
479}
480
481impl From<f64> for Value {
482 fn from(n: f64) -> Self { Value::Float(n) }
483}
484
485impl From<bool> for Value {
486 fn from(b: bool) -> Self { Value::Bool(b) }
487}
488
489impl From<String> for Value {
490 fn from(s: String) -> Self { Value::Text(s) }
491}
492
493impl From<&str> for Value {
494 fn from(s: &str) -> Self { Value::Text(s.to_string()) }
495}
496
497impl From<char> for Value {
498 fn from(c: char) -> Self { Value::Char(c) }
499}
500
501pub type Tuple = Vec<Value>;
503
504impl std::ops::Add for Value {
509 type Output = Value;
510
511 #[inline]
512 fn add(self, other: Value) -> Value {
513 match (self, other) {
514 (Value::Int(a), Value::Int(b)) => Value::Int(a + b),
515 (Value::Float(a), Value::Float(b)) => Value::Float(a + b),
516 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 + b),
517 (Value::Float(a), Value::Int(b)) => Value::Float(a + b as f64),
518 (Value::Text(a), Value::Text(b)) => Value::Text(format!("{}{}", a, b)),
519 _ => panic!("Cannot add these value types"),
520 }
521 }
522}
523
524impl std::ops::Sub for Value {
525 type Output = Value;
526
527 #[inline]
528 fn sub(self, other: Value) -> Value {
529 match (self, other) {
530 (Value::Int(a), Value::Int(b)) => Value::Int(a - b),
531 (Value::Float(a), Value::Float(b)) => Value::Float(a - b),
532 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 - b),
533 (Value::Float(a), Value::Int(b)) => Value::Float(a - b as f64),
534 _ => panic!("Cannot subtract these value types"),
535 }
536 }
537}
538
539impl std::ops::Mul for Value {
540 type Output = Value;
541
542 #[inline]
543 fn mul(self, other: Value) -> Value {
544 match (self, other) {
545 (Value::Int(a), Value::Int(b)) => Value::Int(a * b),
546 (Value::Float(a), Value::Float(b)) => Value::Float(a * b),
547 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 * b),
548 (Value::Float(a), Value::Int(b)) => Value::Float(a * b as f64),
549 _ => panic!("Cannot multiply these value types"),
550 }
551 }
552}
553
554impl std::ops::Div for Value {
555 type Output = Value;
556
557 #[inline]
558 fn div(self, other: Value) -> Value {
559 match (self, other) {
560 (Value::Int(a), Value::Int(b)) => Value::Int(a / b),
561 (Value::Float(a), Value::Float(b)) => Value::Float(a / b),
562 (Value::Int(a), Value::Float(b)) => Value::Float(a as f64 / b),
563 (Value::Float(a), Value::Int(b)) => Value::Float(a / b as f64),
564 _ => panic!("Cannot divide these value types"),
565 }
566 }
567}
568
569#[cfg(test)]
570mod tests {
571 use super::*;
572
573 #[test]
574 fn value_int_arithmetic() {
575 assert_eq!(Value::Int(10) + Value::Int(3), Value::Int(13));
576 assert_eq!(Value::Int(10) - Value::Int(3), Value::Int(7));
577 assert_eq!(Value::Int(10) * Value::Int(3), Value::Int(30));
578 assert_eq!(Value::Int(10) / Value::Int(3), Value::Int(3));
579 }
580
581 #[test]
582 fn value_float_arithmetic() {
583 assert_eq!(Value::Float(2.5) + Value::Float(1.5), Value::Float(4.0));
584 assert_eq!(Value::Float(5.0) - Value::Float(1.5), Value::Float(3.5));
585 assert_eq!(Value::Float(2.0) * Value::Float(3.0), Value::Float(6.0));
586 assert_eq!(Value::Float(7.0) / Value::Float(2.0), Value::Float(3.5));
587 }
588
589 #[test]
590 fn value_cross_type_promotion() {
591 assert_eq!(Value::Int(2) + Value::Float(1.5), Value::Float(3.5));
592 assert_eq!(Value::Float(2.5) + Value::Int(2), Value::Float(4.5));
593 assert_eq!(Value::Int(3) * Value::Float(2.0), Value::Float(6.0));
594 assert_eq!(Value::Float(6.0) / Value::Int(2), Value::Float(3.0));
595 }
596
597 #[test]
598 fn value_text_concat() {
599 assert_eq!(
600 Value::Text("hello".to_string()) + Value::Text(" world".to_string()),
601 Value::Text("hello world".to_string())
602 );
603 }
604
605 #[test]
606 #[should_panic(expected = "divide by zero")]
607 fn value_div_by_zero_panics() {
608 let _ = Value::Int(1) / Value::Int(0);
609 }
610
611 #[test]
612 #[should_panic(expected = "Cannot add")]
613 fn value_incompatible_types_panic() {
614 let _ = Value::Bool(true) + Value::Int(1);
615 }
616
617 #[test]
618 fn value_display() {
619 assert_eq!(format!("{}", Value::Int(42)), "42");
620 assert_eq!(format!("{}", Value::Float(3.14)), "3.14");
621 assert_eq!(format!("{}", Value::Bool(true)), "true");
622 assert_eq!(format!("{}", Value::Text("hi".to_string())), "hi");
623 assert_eq!(format!("{}", Value::Char('a')), "a");
624 assert_eq!(format!("{}", Value::Nothing), "nothing");
625 }
626
627 #[test]
628 fn value_from_conversions() {
629 assert_eq!(Value::from(42i64), Value::Int(42));
630 assert_eq!(Value::from(3.14f64), Value::Float(3.14));
631 assert_eq!(Value::from(true), Value::Bool(true));
632 assert_eq!(Value::from("hello"), Value::Text("hello".to_string()));
633 assert_eq!(Value::from("hello".to_string()), Value::Text("hello".to_string()));
634 assert_eq!(Value::from('x'), Value::Char('x'));
635 }
636}