use serde::{Deserialize, Serialize};
use std::fmt;
use uuid::Uuid;
use crate::error::CoreError;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct WorkflowId(String);
impl WorkflowId {
pub fn new(id: impl Into<String>) -> Result<Self, CoreError> {
let id = id.into();
if id.is_empty() {
return Err(CoreError::InvalidId("WorkflowId cannot be empty".to_string()));
}
Ok(Self(id))
}
#[must_use]
pub fn generate() -> Self {
Self(Uuid::new_v4().to_string())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for WorkflowId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct PlanId(String);
impl PlanId {
pub fn new(id: impl Into<String>) -> Result<Self, CoreError> {
let id = id.into();
if id.is_empty() {
return Err(CoreError::InvalidId("PlanId cannot be empty".to_string()));
}
Ok(Self(id))
}
#[must_use]
pub fn generate() -> Self {
Self(Uuid::new_v4().to_string())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for PlanId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct StepId(String);
impl StepId {
pub fn new(id: impl Into<String>) -> Result<Self, CoreError> {
let id = id.into();
if id.is_empty() {
return Err(CoreError::InvalidId("StepId cannot be empty".to_string()));
}
Ok(Self(id))
}
#[must_use]
pub fn generate() -> Self {
Self(Uuid::new_v4().to_string())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for StepId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ExecutionId(String);
impl ExecutionId {
pub fn new(id: impl Into<String>) -> Result<Self, CoreError> {
let id = id.into();
if id.is_empty() {
return Err(CoreError::InvalidId("ExecutionId cannot be empty".to_string()));
}
Ok(Self(id))
}
#[must_use]
pub fn generate() -> Self {
Self(Uuid::new_v4().to_string())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for ExecutionId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct DecisionId(String);
impl DecisionId {
pub fn new(id: impl Into<String>) -> Result<Self, CoreError> {
let id = id.into();
if id.is_empty() {
return Err(CoreError::InvalidId("DecisionId cannot be empty".to_string()));
}
Ok(Self(id))
}
#[must_use]
pub fn generate() -> Self {
Self(Uuid::new_v4().to_string())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for DecisionId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_workflow_id_new() {
let id = WorkflowId::new("test-workflow").unwrap();
assert_eq!(id.as_str(), "test-workflow");
}
#[test]
fn test_workflow_id_empty() {
let result = WorkflowId::new("");
assert!(result.is_err());
}
#[test]
fn test_workflow_id_generate() {
let id1 = WorkflowId::generate();
let id2 = WorkflowId::generate();
assert_ne!(id1, id2);
}
#[test]
fn test_plan_id_new() {
let id = PlanId::new("test-plan").unwrap();
assert_eq!(id.as_str(), "test-plan");
}
#[test]
fn test_step_id_new() {
let id = StepId::new("test-step").unwrap();
assert_eq!(id.as_str(), "test-step");
}
#[test]
fn test_execution_id_new() {
let id = ExecutionId::new("test-execution").unwrap();
assert_eq!(id.as_str(), "test-execution");
}
#[test]
fn test_decision_id_new() {
let id = DecisionId::new("test-decision").unwrap();
assert_eq!(id.as_str(), "test-decision");
}
}