Make IndexableValue into a total order

This commit is contained in:
Yuriy Dupyn 2024-02-01 15:22:03 +01:00
parent dab4fdd02b
commit 6b93452d3e

View file

@ -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<DbType>)
}
impl PartialOrd for DbType {
// TODO: Explain why we need this (because of IndexableValue::None contains a type)
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
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<Ordering> {
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(),
}