Skip to content

Commit

Permalink
feat: implement more operations
Browse files Browse the repository at this point in the history
  • Loading branch information
JabobKrauskopf committed Sep 30, 2024
1 parent 2958867 commit 54c1378
Show file tree
Hide file tree
Showing 21 changed files with 1,899 additions and 366 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/medmodels-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ serde = { workspace = true }
chrono = { workspace = true }
ron = "0.8.1"
roaring = "0.10.6"
itertools = "0.13.0"
46 changes: 24 additions & 22 deletions crates/medmodels-core/src/medrecord/datatypes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#![allow(dead_code)]
// TODO: Remove the above line after query engine is implemented

mod attribute;
mod value;

Expand Down Expand Up @@ -54,6 +51,24 @@ impl From<&MedRecordValue> for DataType {
}
}

impl From<MedRecordAttribute> for DataType {
fn from(value: MedRecordAttribute) -> Self {
match value {
MedRecordAttribute::String(_) => DataType::String,
MedRecordAttribute::Int(_) => DataType::Int,
}
}
}

impl From<&MedRecordAttribute> for DataType {
fn from(value: &MedRecordAttribute) -> Self {
match value {
MedRecordAttribute::String(_) => DataType::String,
MedRecordAttribute::Int(_) => DataType::Int,
}
}
}

impl PartialEq for DataType {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
Expand Down Expand Up @@ -129,14 +144,6 @@ impl DataType {
}
}

pub trait Pow: Sized {
fn pow(self, exp: Self) -> Result<Self, MedRecordError>;
}

pub trait Mod: Sized {
fn r#mod(self, other: Self) -> Result<Self, MedRecordError>;
}

pub trait StartsWith {
fn starts_with(&self, other: &Self) -> bool;
}
Expand All @@ -149,8 +156,12 @@ pub trait Contains {
fn contains(&self, other: &Self) -> bool;
}

pub trait PartialNeq: PartialEq {
fn neq(&self, other: &Self) -> bool;
pub trait Pow: Sized {
fn pow(self, exp: Self) -> Result<Self, MedRecordError>;
}

pub trait Mod: Sized {
fn r#mod(self, other: Self) -> Result<Self, MedRecordError>;
}

pub trait Round {
Expand Down Expand Up @@ -197,15 +208,6 @@ pub trait Slice {
fn slice(self, range: Range<usize>) -> Self;
}

impl<T> PartialNeq for T
where
T: PartialOrd,
{
fn neq(&self, other: &Self) -> bool {
self != other
}
}

#[cfg(test)]
mod test {
use super::{DataType, MedRecordValue};
Expand Down
107 changes: 74 additions & 33 deletions crates/medmodels-core/src/medrecord/datatypes/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{
Trim, TrimEnd, TrimStart, Uppercase,
};
use crate::errors::MedRecordError;
use chrono::NaiveDateTime;
use chrono::{DateTime, NaiveDateTime};
use medmodels_utils::implement_from_for_wrapper;
use serde::{Deserialize, Serialize};
use std::{
Expand Down Expand Up @@ -210,9 +210,17 @@ impl Add for MedRecordValue {
(MedRecordValue::DateTime(value), MedRecordValue::Bool(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot add {} to {}", rhs, value)),
),
(MedRecordValue::DateTime(value), MedRecordValue::DateTime(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot add {} to {}", rhs, value)),
),
(MedRecordValue::DateTime(value), MedRecordValue::DateTime(rhs)) => {
Ok(DateTime::from_timestamp(
value.and_utc().timestamp() + rhs.and_utc().timestamp(),
0,
)
.ok_or(MedRecordError::AssertionError(
"Invalid timestamp".to_string(),
))?
.naive_utc()
.into())
}
(MedRecordValue::DateTime(value), MedRecordValue::Null) => Err(
MedRecordError::AssertionError(format!("Cannot add None to {}", value)),
),
Expand Down Expand Up @@ -327,9 +335,17 @@ impl Sub for MedRecordValue {
(MedRecordValue::DateTime(value), MedRecordValue::Bool(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot subtract {} from {}", rhs, value)),
),
(MedRecordValue::DateTime(value), MedRecordValue::DateTime(rhs)) => Err(
MedRecordError::AssertionError(format!("Cannot subtract {} from {}", rhs, value)),
),
(MedRecordValue::DateTime(value), MedRecordValue::DateTime(rhs)) => {
Ok(DateTime::from_timestamp(
value.and_utc().timestamp() - rhs.and_utc().timestamp(),
0,
)
.ok_or(MedRecordError::AssertionError(
"Invalid timestamp".to_string(),
))?
.naive_utc()
.into())
}
(MedRecordValue::DateTime(value), MedRecordValue::Null) => Err(
MedRecordError::AssertionError(format!("Cannot subtract None from {}", value)),
),
Expand Down Expand Up @@ -621,9 +637,17 @@ impl Div for MedRecordValue {
(MedRecordValue::DateTime(value), MedRecordValue::String(other)) => Err(
MedRecordError::AssertionError(format!("Cannot divide {} by {}", value, other)),
),
(MedRecordValue::DateTime(value), MedRecordValue::Int(other)) => Err(
MedRecordError::AssertionError(format!("Cannot divide {} by {}", value, other)),
),
(MedRecordValue::DateTime(value), MedRecordValue::Int(other)) => {
Ok(DateTime::from_timestamp(
(value.and_utc().timestamp() as f64 / other as f64).floor() as i64,
0,
)
.ok_or(MedRecordError::AssertionError(
"Invalid timestamp".to_string(),
))?
.naive_utc()
.into())
}
(MedRecordValue::DateTime(value), MedRecordValue::Float(other)) => Err(
MedRecordError::AssertionError(format!("Cannot divide {} by {}", value, other)),
),
Expand Down Expand Up @@ -1183,7 +1207,7 @@ mod test {
Uppercase,
},
};
use chrono::NaiveDateTime;
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime};

#[test]
fn test_default() {
Expand Down Expand Up @@ -1669,9 +1693,23 @@ mod test {
(MedRecordValue::DateTime(NaiveDateTime::MIN) + MedRecordValue::Bool(false))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!((MedRecordValue::DateTime(NaiveDateTime::MIN)
+ MedRecordValue::DateTime(NaiveDateTime::MIN))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert_eq!(
MedRecordValue::DateTime(
NaiveDate::from_ymd_opt(1970, 1, 4)
.unwrap()
.and_time(NaiveTime::MIN)
),
(MedRecordValue::DateTime(
NaiveDate::from_ymd_opt(1970, 1, 2)
.unwrap()
.and_time(NaiveTime::MIN)
) + MedRecordValue::DateTime(
NaiveDate::from_ymd_opt(1970, 1, 3)
.unwrap()
.and_time(NaiveTime::MIN)
))
.unwrap()
);
assert!(
(MedRecordValue::DateTime(NaiveDateTime::MIN) + MedRecordValue::Null)
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
Expand Down Expand Up @@ -1794,9 +1832,12 @@ mod test {
(MedRecordValue::DateTime(NaiveDateTime::MIN) - MedRecordValue::Bool(false))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!((MedRecordValue::DateTime(NaiveDateTime::MIN)
- MedRecordValue::DateTime(NaiveDateTime::MIN))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert_eq!(
MedRecordValue::DateTime(DateTime::from_timestamp(0, 0).unwrap().naive_utc()),
(MedRecordValue::DateTime(NaiveDateTime::MAX)
- MedRecordValue::DateTime(NaiveDateTime::MAX))
.unwrap()
);
assert!(
(MedRecordValue::DateTime(NaiveDateTime::MIN) - MedRecordValue::Null)
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
Expand Down Expand Up @@ -1951,15 +1992,15 @@ mod test {
/ MedRecordValue::String("value".to_string()))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!(
(MedRecordValue::String("value".to_string()) / MedRecordValue::Int(0))
(MedRecordValue::String("value".to_string()) / MedRecordValue::Int(1))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!(
(MedRecordValue::String("value".to_string()) / MedRecordValue::Float(0_f64))
(MedRecordValue::String("value".to_string()) / MedRecordValue::Float(1_f64))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!(
(MedRecordValue::String("value".to_string()) / MedRecordValue::Bool(false))
(MedRecordValue::String("value".to_string()) / MedRecordValue::Bool(true))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!((MedRecordValue::String("value".to_string())
Expand All @@ -1982,7 +2023,7 @@ mod test {
MedRecordValue::Float(1_f64),
(MedRecordValue::Int(5) / MedRecordValue::Float(5_f64)).unwrap()
);
assert!((MedRecordValue::Int(0) / MedRecordValue::Bool(false))
assert!((MedRecordValue::Int(0) / MedRecordValue::Bool(true))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!(
(MedRecordValue::Int(0) / MedRecordValue::DateTime(NaiveDateTime::MIN))
Expand All @@ -2003,7 +2044,7 @@ mod test {
MedRecordValue::Float(1_f64),
(MedRecordValue::Float(5_f64) / MedRecordValue::Float(5_f64)).unwrap()
);
assert!((MedRecordValue::Float(0_f64) / MedRecordValue::Bool(false))
assert!((MedRecordValue::Float(0_f64) / MedRecordValue::Bool(true))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!(
(MedRecordValue::Float(0_f64) / MedRecordValue::DateTime(NaiveDateTime::MIN))
Expand All @@ -2016,11 +2057,11 @@ mod test {
(MedRecordValue::Bool(false) / MedRecordValue::String("value".to_string()))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!((MedRecordValue::Bool(false) / MedRecordValue::Int(0))
assert!((MedRecordValue::Bool(false) / MedRecordValue::Int(1))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!((MedRecordValue::Bool(false) / MedRecordValue::Float(0_f64))
assert!((MedRecordValue::Bool(false) / MedRecordValue::Float(1_f64))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!((MedRecordValue::Bool(false) / MedRecordValue::Bool(false))
assert!((MedRecordValue::Bool(false) / MedRecordValue::Bool(true))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!(
(MedRecordValue::Bool(false) / MedRecordValue::DateTime(NaiveDateTime::MIN))
Expand All @@ -2032,16 +2073,16 @@ mod test {
assert!((MedRecordValue::DateTime(NaiveDateTime::MIN)
/ MedRecordValue::String("value".to_string()))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!(
(MedRecordValue::DateTime(NaiveDateTime::MIN) / MedRecordValue::Int(0))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
assert_eq!(
MedRecordValue::DateTime(NaiveDateTime::MIN),
(MedRecordValue::DateTime(NaiveDateTime::MIN) / MedRecordValue::Int(1)).unwrap()
);
assert!(
(MedRecordValue::DateTime(NaiveDateTime::MIN) / MedRecordValue::Float(0_f64))
(MedRecordValue::DateTime(NaiveDateTime::MIN) / MedRecordValue::Float(1_f64))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!(
(MedRecordValue::DateTime(NaiveDateTime::MIN) / MedRecordValue::Bool(false))
(MedRecordValue::DateTime(NaiveDateTime::MIN) / MedRecordValue::Bool(true))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!((MedRecordValue::DateTime(NaiveDateTime::MIN)
Expand All @@ -2056,11 +2097,11 @@ mod test {
(MedRecordValue::Null / MedRecordValue::String("value".to_string()))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_)))
);
assert!((MedRecordValue::Null / MedRecordValue::Int(0))
assert!((MedRecordValue::Null / MedRecordValue::Int(1))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!((MedRecordValue::Null / MedRecordValue::Float(0_f64))
assert!((MedRecordValue::Null / MedRecordValue::Float(1_f64))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!((MedRecordValue::Null / MedRecordValue::Bool(false))
assert!((MedRecordValue::Null / MedRecordValue::Bool(true))
.is_err_and(|e| matches!(e, MedRecordError::AssertionError(_))));
assert!(
(MedRecordValue::Null / MedRecordValue::DateTime(NaiveDateTime::MIN))
Expand Down
13 changes: 11 additions & 2 deletions crates/medmodels-core/src/medrecord/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1924,7 +1924,7 @@ mod test {
(
"0".into(),
"1".into(),
HashMap::from([("time".into(), 4.into())]),
HashMap::from([("time".into(), "Hallo".into())]),
),
(
"0".into(),
Expand All @@ -1943,7 +1943,16 @@ mod test {
.unwrap();

let nodes = medrecord.select_edges(|edge| {
edge.attribute("time").less_than(2);
let attribute = edge.attribute("time");
attribute.is_int();
attribute.either_or(
|attribute| {
attribute.greater_than(4);
},
|attribute| {
attribute.less_than(2);
},
);
});

println!("\n{:?}", nodes.collect::<Vec<_>>());
Expand Down
Loading

0 comments on commit 54c1378

Please sign in to comment.