diff --git a/crates/ascend/src/models.rs b/crates/ascend/src/models.rs index 8ddc100..272969b 100644 --- a/crates/ascend/src/models.rs +++ b/crates/ascend/src/models.rs @@ -8,7 +8,6 @@ pub use v2::ImageFilename; pub use v2::ImageResolution; pub use v2::ImageUid; pub use v2::Method; -pub use v2::Problem; pub use v2::ProblemUid; pub use v2::Root; pub use v2::Wall; @@ -17,13 +16,45 @@ pub use v2::WallUid; pub use v3::Attempt; pub use v3::UserInteraction; pub use v4::DatedAttempt; +pub use v4::Problem; +pub use v4::ProblemHolds; mod semantics; pub mod v4 { + use super::v1; + use super::v2; use super::v3; use chrono::DateTime; use chrono::Utc; + use serde::Deserialize; + use serde::Serialize; + use std::collections::BTreeMap; + use std::collections::BTreeSet; + + #[derive(Serialize, Deserialize, Debug, Clone)] + pub struct Wall { + pub uid: v2::WallUid, + pub wall_dimensions: v2::WallDimensions, + pub holds: BTreeMap, + pub problems: BTreeSet, + } + + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] + pub struct Problem { + pub holds: ProblemHolds, + pub method: v2::Method, + pub transformation: Transformation, + } + + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] + pub struct Transformation { + pub horizontal_shift: u64, + pub mirror: bool, + } + + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] + pub struct ProblemHolds(pub BTreeMap); #[derive(Debug, Clone, Copy)] pub struct DatedAttempt { @@ -93,7 +124,7 @@ pub mod v2 { pub problems: BTreeSet, } - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct WallDimensions { pub rows: u64, pub cols: u64, @@ -115,7 +146,7 @@ pub mod v2 { #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, derive_more::FromStr, derive_more::Display)] pub struct ProblemUid(pub uuid::Uuid); - #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Display)] + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Display, Copy)] pub enum Method { #[display("Feet follow hands")] FeetFollowHands, diff --git a/crates/ascend/src/models/semantics.rs b/crates/ascend/src/models/semantics.rs index f9288fa..da42f99 100644 --- a/crates/ascend/src/models/semantics.rs +++ b/crates/ascend/src/models/semantics.rs @@ -3,6 +3,89 @@ use chrono::DateTime; use chrono::Utc; use std::collections::BTreeMap; +impl Problem { + pub fn normalize(&self) -> Self { + let Self { + holds, + method, + transformation, + } = self; + + let min_col = holds.0.iter().map(|(hold_position, _)| hold_position.col).min().unwrap_or(0); + + let holds = { + let holds = holds + .0 + .iter() + .map(|(hold_position, hold_role)| { + let hold_position = HoldPosition { + row: hold_position.row, + col: hold_position.col - min_col, + }; + (hold_position, *hold_role) + }) + .collect(); + ProblemHolds(holds) + }; + + let transformation = { + let mut transformation = *transformation; + transformation.horizontal_shift += min_col; + transformation + }; + + Self { + holds, + method: *method, + transformation, + } + } + + pub fn mirror(&self) -> Self { + let Self { + holds, + method, + transformation, + } = self; + + let min_col = holds.0.iter().map(|(hold_position, _)| hold_position.col).min().unwrap_or(0); + let max_col = holds.0.iter().map(|(hold_position, _)| hold_position.col).max().unwrap_or(0); + + let holds = { + let holds = holds + .0 + .iter() + .map(|(hold_position, hold_role)| { + let HoldPosition { row, col } = *hold_position; + let mut mirrored_col = col; + mirrored_col += 2 * (max_col - col); + mirrored_col -= max_col - min_col; + let hold_position = HoldPosition { row, col: mirrored_col }; + (hold_position, *hold_role) + }) + .collect(); + ProblemHolds(holds) + }; + + let transformation = { + let mut transformation = *transformation; + transformation.mirror = !transformation.mirror; + transformation + }; + + Self { + holds, + method: *method, + transformation, + } + .normalize() + } + + pub fn shift(&self, shift: i64) -> Self { + todo!() + } +} + impl UserInteraction { pub(crate) fn new(wall_uid: WallUid, problem_uid: ProblemUid) -> Self { Self { diff --git a/crates/ascend/src/server/db.rs b/crates/ascend/src/server/db.rs index 33ee685..a3da7c0 100644 --- a/crates/ascend/src/server/db.rs +++ b/crates/ascend/src/server/db.rs @@ -154,6 +154,16 @@ pub mod current { pub use v3::VERSION; } +pub mod v4 { + use crate::models; + use crate::server::db::bincode::Bincode; + use redb::TableDefinition; + + pub const VERSION: u64 = 4; + + // TODO +} + pub mod v3 { use crate::models; use crate::server::db::bincode::Bincode;