use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::ids::{CaseId, CaseRevision, WorkflowKey};
#[derive(
Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
pub struct CaseKey {
pub workflow: WorkflowKey,
pub case_id: CaseId,
}
impl CaseKey {
#[must_use]
pub fn new(workflow: impl Into<WorkflowKey>, case_id: impl Into<CaseId>) -> Self {
Self {
workflow: workflow.into(),
case_id: case_id.into(),
}
}
#[must_use]
pub fn at(self, expected_revision: CaseRevision) -> CaseRef {
CaseRef {
workflow: self.workflow,
case_id: self.case_id,
expected_revision,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
pub struct CaseRef {
pub workflow: WorkflowKey,
pub case_id: CaseId,
pub expected_revision: CaseRevision,
}
impl CaseRef {
#[must_use]
pub fn new(
workflow: impl Into<WorkflowKey>,
case_id: impl Into<CaseId>,
expected_revision: CaseRevision,
) -> Self {
Self {
workflow: workflow.into(),
case_id: case_id.into(),
expected_revision,
}
}
#[must_use]
pub fn key(&self) -> CaseKey {
CaseKey {
workflow: self.workflow.clone(),
case_id: self.case_id.clone(),
}
}
#[must_use]
pub fn with_revision(&self, revision: CaseRevision) -> Self {
Self {
workflow: self.workflow.clone(),
case_id: self.case_id.clone(),
expected_revision: revision,
}
}
#[must_use]
pub fn same_case(&self, other: &CaseRef) -> bool {
self.workflow == other.workflow && self.case_id == other.case_id
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Versioned<T> {
pub value: T,
pub revision: CaseRevision,
}
impl<T> Versioned<T> {
#[must_use]
pub const fn new(value: T, revision: CaseRevision) -> Self {
Self { value, revision }
}
#[must_use]
pub const fn as_ref(&self) -> Versioned<&T> {
Versioned {
value: &self.value,
revision: self.revision,
}
}
#[must_use]
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Versioned<U> {
Versioned {
value: f(self.value),
revision: self.revision,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn case_ref_key_and_revision_helpers() {
let r = CaseRef::new("trip", "trip-1", CaseRevision(4));
assert_eq!(r.key(), CaseKey::new("trip", "trip-1"));
assert_eq!(
r.with_revision(CaseRevision(5)).expected_revision,
CaseRevision(5)
);
assert!(r.same_case(&r.with_revision(CaseRevision(9))));
assert_eq!(CaseKey::new("trip", "trip-1").at(CaseRevision(4)), r);
}
#[test]
fn versioned_map_keeps_revision() {
let v = Versioned::new(2_u32, CaseRevision(7)).map(|n| n * 2);
assert_eq!(v.value, 4);
assert_eq!(v.revision, CaseRevision(7));
}
}