Created
October 17, 2025 17:43
-
-
Save skull-squadron/aef147423bd8f993ca907515215c9584 to your computer and use it in GitHub Desktop.
Rust concrete typed ontology
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use serde::{Deserialize, Serialize}; | |
| use std::{ | |
| collections::{HashMap, HashSet, LinkedList}, | |
| convert::From, | |
| hash::{Hash, Hasher}, | |
| }; | |
| #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | |
| #[repr(u8)] | |
| pub enum Literal { | |
| Atom(String), | |
| String(String), | |
| Char(char), | |
| Bool(bool), | |
| Int8(i8), | |
| Int16(i16), | |
| Int32(i32), | |
| Int64(i64), | |
| Int128(i128), | |
| ISize(isize), | |
| UInt8(u8), | |
| UInt16(u16), | |
| UInt32(u32), | |
| UInt64(u64), | |
| UInt128(u128), | |
| USize(usize), | |
| Float32(f32), | |
| Float64(f64), | |
| Void, | |
| } | |
| impl Literal { | |
| pub const fn discriminant(&self) -> u8 { | |
| unsafe { *(self as *const Self as *const u8) } | |
| } | |
| fn hash_with_discriminant<T: Hash>(&self, state: &mut impl Hasher, x: Option<T>) { | |
| self.discriminant().hash(state); | |
| x.map(|x| x.hash(state)); | |
| } | |
| pub fn atom(s: impl AsRef<str>) -> Self { | |
| Self::Atom(s.as_ref().to_string()) | |
| } | |
| } | |
| macro_rules! impl_from_for_literal { | |
| ($($f:ty => $t:expr),+ $(,)?) => { | |
| $( | |
| impl From<$f> for Literal { | |
| fn from(value: $f) -> Self { | |
| $t(value.into()) | |
| } | |
| } | |
| )+ | |
| } | |
| } | |
| impl_from_for_literal!( | |
| &str => Literal::String, | |
| String => Literal::String, | |
| char => Literal::Char, | |
| bool => Literal::Bool, | |
| i8 => Literal::Int8, | |
| i16 => Literal::Int16, | |
| i32 => Literal::Int32, | |
| i64 => Literal::Int64, | |
| i128 => Literal::Int128, | |
| isize => Literal::ISize, | |
| u8 => Literal::UInt8, | |
| u16 => Literal::UInt16, | |
| u32 => Literal::UInt32, | |
| u64 => Literal::UInt64, | |
| u128 => Literal::UInt128, | |
| usize => Literal::USize, | |
| f32 => Literal::Float32, | |
| f64 => Literal::Float64, | |
| ); | |
| impl From<std::string::Drain<'_>> for Literal { | |
| fn from(st: std::string::Drain) -> Self { | |
| Literal::String(st.as_str().to_string()) | |
| } | |
| } | |
| impl From<()> for Literal { | |
| fn from(_: ()) -> Self { | |
| Literal::Void | |
| } | |
| } | |
| impl Eq for Literal {} | |
| impl Hash for Literal { | |
| fn hash<H: Hasher>(&self, state: &mut H) { | |
| use Literal::*; | |
| match self { | |
| Atom(x) => self.hash_with_discriminant(state, Some(x)), | |
| String(x) => self.hash_with_discriminant(state, Some(x)), | |
| Char(x) => self.hash_with_discriminant(state, Some(x)), | |
| Bool(x) => self.hash_with_discriminant(state, Some(x)), | |
| Int8(x) => self.hash_with_discriminant(state, Some(x)), | |
| Int16(x) => self.hash_with_discriminant(state, Some(x)), | |
| Int32(x) => self.hash_with_discriminant(state, Some(x)), | |
| Int64(x) => self.hash_with_discriminant(state, Some(x)), | |
| Int128(x) => self.hash_with_discriminant(state, Some(x)), | |
| ISize(x) => self.hash_with_discriminant(state, Some(x)), | |
| UInt8(x) => self.hash_with_discriminant(state, Some(x)), | |
| UInt16(x) => self.hash_with_discriminant(state, Some(x)), | |
| UInt32(x) => self.hash_with_discriminant(state, Some(x)), | |
| UInt64(x) => self.hash_with_discriminant(state, Some(x)), | |
| UInt128(x) => self.hash_with_discriminant(state, Some(x)), | |
| USize(x) => self.hash_with_discriminant(state, Some(x)), | |
| Float32(x) => self.hash_with_discriminant(state, Some(x.to_bits())), | |
| Float64(x) => self.hash_with_discriminant(state, Some(x.to_bits())), | |
| Void => self.hash_with_discriminant(state, None::<()>), | |
| } | |
| } | |
| } | |
| #[derive(Debug, Clone, Serialize, Deserialize)] | |
| pub enum Value { | |
| Comment(String), | |
| Dict(HashMap<Literal, Value>), | |
| Set(HashSet<Literal>), | |
| List(LinkedList<Value>), | |
| Array(Vec<Value>), | |
| Tuple(Vec<Value>), | |
| Literal(Literal), | |
| } | |
| macro_rules! impl_partial_eq_for_value { | |
| ($($t:tt),+ $(,)?) => { | |
| impl PartialEq for Value { | |
| fn eq(&self, other: &Self) -> bool { | |
| use Value::*; | |
| match (self, other) { | |
| $(($t(x), $t(y)) => x == y,)+ | |
| _ => false, | |
| } | |
| } | |
| } | |
| }; | |
| } | |
| impl_partial_eq_for_value!(Comment, Dict, Set, List, Array, Tuple, Literal); | |
| impl<T> From<T> for Value | |
| where | |
| Literal: From<T>, | |
| { | |
| fn from(value: T) -> Self { | |
| Value::Literal(value.into()) | |
| } | |
| } | |
| /* | |
| impl<'a, T: ?Sized> From<&'a T> for Value where Literal: From<&'a T>, Self: 'a{ | |
| fn from(value: &'a T) -> Self { | |
| Value::Literal(value.into()) | |
| } | |
| } | |
| */ | |
| macro_rules! impl_ref_from_for_value { | |
| ($($f:ty => $tmp:ty => $t:expr),+ $(,)?) => { | |
| $( | |
| impl From<$f> for Value { | |
| fn from(value: $f) -> Self { | |
| $t(value.into_iter().cloned().collect::<$tmp>().into()) | |
| } | |
| } | |
| )+ | |
| } | |
| } | |
| macro_rules! impl_from_for_value { | |
| ($($f:ty => $t:expr),+ $(,)?) => { | |
| $( | |
| impl From<&$f> for Value { | |
| fn from(value: &$f) -> Self { | |
| $t(value.clone()) | |
| } | |
| } | |
| impl From<$f> for Value { | |
| fn from(value: $f) -> Self { | |
| $t(value) | |
| } | |
| } | |
| )+ | |
| } | |
| } | |
| impl_ref_from_for_value!( | |
| Vec<&Value> => Vec<Value> => Value::Array, | |
| ); | |
| impl_from_for_value!( | |
| HashSet<Literal> => Value::Set, | |
| HashMap<Literal, Value> => Value::Dict, | |
| LinkedList<Value> => Value::List, | |
| Vec<Value> => Value::Array, | |
| ); | |
| /* | |
| fn main() { | |
| let x: Value = "hello".into(); | |
| println!("{x:?}"); | |
| let y: Value = 1u8.into(); | |
| println!("{y:?}"); | |
| let a: Value = vec![x, y].into(); | |
| println!("{a:?}"); | |
| let _ = Literal::atom("magic"); | |
| let _ = Literal::atom(&"magic"); | |
| let _ = Literal::atom("magic".to_string()); | |
| let _ = Literal::atom("foo".to_string().drain(..)); | |
| } | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment