diff --git a/minisql/src/type_system.rs b/minisql/src/type_system.rs index 0d3d4b6..8e7b0a1 100644 --- a/minisql/src/type_system.rs +++ b/minisql/src/type_system.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; use serde::{Deserialize, Serialize}; // ==============Types================ -#[derive(Debug, Clone, Ord, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum DbType { String, Int, @@ -12,13 +12,6 @@ pub enum DbType { Option(Box) } -impl PartialOrd for DbType { - // TODO: Explain why we need this (because of IndexableValue::None contains a type) - fn partial_cmp(&self, other: &Self) -> Option { - todo!() - } -} - // ==============Values================ pub type Uuid = u64; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -36,7 +29,7 @@ pub enum Value { } -#[derive(Debug, Ord, Eq, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Eq, Clone, PartialEq, Serialize, Deserialize)] #[serde(try_from = "String", into = "String")] pub enum IndexableValue { String(String), @@ -48,7 +41,42 @@ pub enum IndexableValue { impl PartialOrd for IndexableValue { fn partial_cmp(&self, other: &Self) -> Option { - todo!() + match (self, other) { + (IndexableValue::String(s0), IndexableValue::String(s1)) => s0.partial_cmp(s1), + (IndexableValue::Int(n0), IndexableValue::Int(n1)) => n0.partial_cmp(n1), + (IndexableValue::Uuid(id0), IndexableValue::Uuid(id1)) => id0.partial_cmp(id1), + (IndexableValue::None(_), IndexableValue::None(_)) => Some(Ordering::Equal), + (IndexableValue::None(_), IndexableValue::Some(_)) => Some(Ordering::Less), + (IndexableValue::Some(_), IndexableValue::None(_)) => Some(Ordering::Greater), + (IndexableValue::Some(v0), IndexableValue::Some(v1)) => v0.partial_cmp(v1), + _ => None + } + } +} + +impl Ord for IndexableValue { + fn cmp(&self, other: &Self) -> Ordering { + match (self, other) { + (IndexableValue::String(s0), IndexableValue::String(s1)) => s0.cmp(s1), + (IndexableValue::Int(n0), IndexableValue::Int(n1)) => n0.cmp(n1), + (IndexableValue::Uuid(id0), IndexableValue::Uuid(id1)) => id0.cmp(id1), + (IndexableValue::None(_), IndexableValue::None(_)) => Ordering::Equal, + (IndexableValue::None(_), IndexableValue::Some(_)) => Ordering::Less, + (IndexableValue::Some(_), IndexableValue::None(_)) => Ordering::Greater, + (IndexableValue::Some(v0), IndexableValue::Some(v1)) => v0.cmp(v1), + _ => + // SAFETY: + // We are using indexable values as keys in key-value maps. + // When validation is done, it can't happen that we will be comparing two values + // of different types. + // Ofcourse another option is to artificialy order e.g. + // None < Some(...) < String < Int < Uuid + // where ... is again None < Some(...) < String < Int < Uuid + // where ... + // infinitely deep total order. But this is pointless for our usecase. + unreachable!() + } + } } @@ -156,7 +184,6 @@ fn indexable_value_to_string(value: IndexableValue) -> String { IndexableValue::String(s) => format!("String({s})"), IndexableValue::Int(i) => format!("Int({i})"), IndexableValue::Uuid(u) => format!("Uuid({u})"), - IndexableValue::Some(val) => format!("Some({})", indexable_value_to_string(*val)), IndexableValue::Some(val) => todo!(), IndexableValue::None(type_) => "None()".to_string(), }