oneiros-model 0.0.6

Shared domain types for oneiros
Documentation
use serde::{Deserialize, Serialize};

use crate::*;

#[derive(Debug, thiserror::Error)]
pub enum CognitionConstructionError {
    #[error("invalid cognition id: {0}")]
    InvalidId(IdParseError),
    #[error("invalid agent id: {0}")]
    InvalidAgentId(IdParseError),
    #[error("invalid created_at timestamp: {0}")]
    InvalidCreatedAt(#[from] TimestampParseError),
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Cognition {
    pub id: CognitionId,
    pub agent_id: AgentId,
    pub texture: TextureName,
    pub content: Content,
    pub created_at: Timestamp,
}

impl Cognition {
    pub fn create(agent_id: AgentId, texture: TextureName, content: Content) -> Self {
        Self {
            id: CognitionId::from(Id::new()),
            agent_id,
            texture,
            content,
            created_at: Timestamp::now(),
        }
    }

    pub fn ref_token(&self) -> RefToken {
        RefToken::new(Ref::cognition(self.id))
    }

    pub fn as_detail(&self) -> String {
        let lines = [
            format!("  Texture: {}", self.texture),
            format!("  Content: {}", self.content),
            format!("  Created: {}", self.created_at),
        ];

        lines.join("\n")
    }

    pub fn as_table_row(&self) -> String {
        let texture = format!("{}", self.texture);
        let content = self.content.as_str();
        let truncated = if content.len() > 80 {
            let end = content.floor_char_boundary(80);
            format!("{}...", &content[..end])
        } else {
            content.to_string()
        };

        format!("{texture:<12} {truncated}")
    }

    pub fn construct_from_db(
        (id, agent_id, texture, content, created_at): (
            impl AsRef<str>,
            impl AsRef<str>,
            impl AsRef<str>,
            impl AsRef<str>,
            impl AsRef<str>,
        ),
    ) -> Result<Self, CognitionConstructionError> {
        Ok(Cognition {
            id: id
                .as_ref()
                .parse()
                .map_err(CognitionConstructionError::InvalidId)?,
            agent_id: agent_id
                .as_ref()
                .parse()
                .map_err(CognitionConstructionError::InvalidAgentId)?,
            texture: TextureName::new(texture),
            content: Content::new(content),
            created_at: Timestamp::parse_str(created_at)?,
        })
    }
}

impl core::fmt::Display for Cognition {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{} {}", self.ref_token(), self.as_table_row())
    }
}

domain_id!(CognitionId);