scout_rs 0.95.95

A Rust client for the synchornizing state with the Scout database
Documentation
use native_db::{native_db, ToKey};
use native_model::{native_model, Model};
use serde::{Deserialize, Serialize};

use super::v1::EntityLifecycle;

// ===== ARTIFACT V16 (id 19, version 10) - source =====
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[native_model(id = 19, version = 10, from = super::v13::ArtifactLocal)]
#[native_db]
pub struct ArtifactLocal {
    pub id: Option<i64>,
    #[primary_key]
    pub id_local: Option<String>,
    #[secondary_key]
    pub ancestor_id_local: Option<String>,
    pub created_at: Option<String>,
    pub file_path: String,
    #[secondary_key]
    pub session_id: Option<i64>,
    pub timestamp_observation: Option<String>,
    pub modality: Option<String>,
    pub source: Option<String>,
    pub device_id: i64,
    pub updated_at: Option<String>,
    pub timestamp_observation_end: String,
    pub has_uploaded_file_to_storage: bool,
    pub upload_url: Option<String>,
    pub upload_url_generated_at: Option<String>,
    pub file_size_bytes: Option<i64>,
    pub tagged_at: Option<String>,
    pub embedded_at: Option<String>,
    pub segmented_at: Option<String>,
    pub tracked_at: Option<String>,
    pub thumbnail_file_path: Option<String>,
    pub thumbnail_generated_at: Option<String>,
    pub proxy_file_path: Option<String>,
    pub proxy_generated_at: Option<String>,
    #[serde(default)]
    pub lifecycle: EntityLifecycle,
    pub lifecycle_changed_at: String,
    #[serde(default)]
    pub lifecycle_changed_by: Option<String>,
    #[serde(default)]
    pub lifecycle_reason: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Artifact {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created_at: Option<String>,
    pub file_path: String,
    pub session_id: Option<i64>,
    pub timestamp_observation: Option<String>,
    pub modality: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub source: Option<String>,
    pub device_id: i64,
    // Omitted when unset so the column default and trigger own the value.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated_at: Option<String>,
    pub timestamp_observation_end: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub file_size_bytes: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tagged_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub embedded_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub segmented_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub tracked_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub thumbnail_file_path: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub thumbnail_generated_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub proxy_file_path: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub proxy_generated_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub processing_blocked_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub processing_blocked_reason: Option<String>,
    #[serde(default)]
    pub lifecycle: EntityLifecycle,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub lifecycle_changed_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub lifecycle_changed_by: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub lifecycle_reason: Option<String>,
}

impl Default for ArtifactLocal {
    fn default() -> Self {
        use chrono::Utc;
        Self {
            id: None,
            id_local: None,
            ancestor_id_local: None,
            created_at: None,
            file_path: String::new(),
            session_id: None,
            timestamp_observation: None,
            modality: None,
            source: None,
            device_id: 0,
            updated_at: None,
            timestamp_observation_end: Utc::now().to_rfc3339(),
            has_uploaded_file_to_storage: false,
            upload_url: None,
            upload_url_generated_at: None,
            file_size_bytes: None,
            tagged_at: None,
            embedded_at: None,
            segmented_at: None,
            tracked_at: None,
            thumbnail_file_path: None,
            thumbnail_generated_at: None,
            proxy_file_path: None,
            proxy_generated_at: None,
            lifecycle: EntityLifecycle::Active,
            lifecycle_changed_at: Utc::now().to_rfc3339(),
            lifecycle_changed_by: None,
            lifecycle_reason: None,
        }
    }
}

impl super::v1::Syncable for ArtifactLocal {
    fn id(&self) -> Option<i64> {
        self.id
    }
    fn set_id(&mut self, id: i64) {
        self.id = Some(id);
    }
    fn id_local(&self) -> Option<String> {
        self.id_local.clone()
    }
    fn set_id_local(&mut self, id_local: String) {
        self.id_local = Some(id_local);
    }
}

impl super::v1::AncestorLocal for ArtifactLocal {
    fn ancestor_id_local(&self) -> Option<String> {
        self.ancestor_id_local.clone()
    }
    fn set_ancestor_id_local(&mut self, ancestor_id_local: String) {
        self.ancestor_id_local = Some(ancestor_id_local);
    }
}

impl From<ArtifactLocal> for Artifact {
    fn from(local: ArtifactLocal) -> Self {
        Self {
            id: local.id,
            created_at: local.created_at,
            file_path: local.file_path,
            session_id: local.session_id,
            timestamp_observation: local.timestamp_observation,
            modality: local.modality,
            source: local.source,
            device_id: local.device_id,
            updated_at: local.updated_at,
            timestamp_observation_end: local.timestamp_observation_end,
            file_size_bytes: local.file_size_bytes,
            tagged_at: local.tagged_at,
            embedded_at: local.embedded_at,
            segmented_at: local.segmented_at,
            tracked_at: local.tracked_at,
            thumbnail_file_path: local.thumbnail_file_path,
            thumbnail_generated_at: local.thumbnail_generated_at,
            proxy_file_path: local.proxy_file_path,
            proxy_generated_at: local.proxy_generated_at,
            processing_blocked_at: None,
            processing_blocked_reason: None,
            lifecycle: local.lifecycle,
            lifecycle_changed_at: Some(local.lifecycle_changed_at),
            lifecycle_changed_by: local.lifecycle_changed_by,
            lifecycle_reason: local.lifecycle_reason,
        }
    }
}

impl From<Artifact> for ArtifactLocal {
    fn from(a: Artifact) -> Self {
        Self {
            id: a.id,
            id_local: None,
            ancestor_id_local: None,
            created_at: a.created_at,
            file_path: a.file_path,
            session_id: a.session_id,
            timestamp_observation: a.timestamp_observation,
            modality: a.modality,
            source: a.source,
            device_id: a.device_id,
            updated_at: a.updated_at,
            timestamp_observation_end: a.timestamp_observation_end,
            has_uploaded_file_to_storage: false,
            upload_url: None,
            upload_url_generated_at: None,
            file_size_bytes: a.file_size_bytes,
            tagged_at: a.tagged_at,
            embedded_at: a.embedded_at,
            segmented_at: a.segmented_at,
            tracked_at: a.tracked_at,
            thumbnail_file_path: a.thumbnail_file_path,
            thumbnail_generated_at: a.thumbnail_generated_at,
            proxy_file_path: a.proxy_file_path,
            proxy_generated_at: a.proxy_generated_at,
            lifecycle: a.lifecycle,
            lifecycle_changed_at: a
                .lifecycle_changed_at
                .unwrap_or_else(|| chrono::Utc::now().to_rfc3339()),
            lifecycle_changed_by: a.lifecycle_changed_by,
            lifecycle_reason: a.lifecycle_reason,
        }
    }
}

impl From<super::v13::ArtifactLocal> for ArtifactLocal {
    fn from(previous: super::v13::ArtifactLocal) -> Self {
        Self {
            id: previous.id,
            id_local: previous.id_local,
            ancestor_id_local: previous.ancestor_id_local,
            created_at: previous.created_at,
            file_path: previous.file_path,
            session_id: previous.session_id,
            timestamp_observation: previous.timestamp_observation,
            modality: previous.modality,
            source: None,
            device_id: previous.device_id,
            updated_at: previous.updated_at,
            timestamp_observation_end: previous.timestamp_observation_end,
            has_uploaded_file_to_storage: previous.has_uploaded_file_to_storage,
            upload_url: previous.upload_url,
            upload_url_generated_at: previous.upload_url_generated_at,
            file_size_bytes: previous.file_size_bytes,
            tagged_at: previous.tagged_at,
            embedded_at: previous.embedded_at,
            segmented_at: previous.segmented_at,
            tracked_at: previous.tracked_at,
            thumbnail_file_path: previous.thumbnail_file_path,
            thumbnail_generated_at: previous.thumbnail_generated_at,
            proxy_file_path: previous.proxy_file_path,
            proxy_generated_at: previous.proxy_generated_at,
            lifecycle: previous.lifecycle,
            lifecycle_changed_at: previous.lifecycle_changed_at,
            lifecycle_changed_by: previous.lifecycle_changed_by,
            lifecycle_reason: previous.lifecycle_reason,
        }
    }
}

impl From<ArtifactLocal> for super::v13::ArtifactLocal {
    fn from(current: ArtifactLocal) -> Self {
        Self {
            id: current.id,
            id_local: current.id_local,
            ancestor_id_local: current.ancestor_id_local,
            created_at: current.created_at,
            file_path: current.file_path,
            session_id: current.session_id,
            timestamp_observation: current.timestamp_observation,
            modality: current.modality,
            device_id: current.device_id,
            updated_at: current.updated_at,
            timestamp_observation_end: current.timestamp_observation_end,
            has_uploaded_file_to_storage: current.has_uploaded_file_to_storage,
            upload_url: current.upload_url,
            upload_url_generated_at: current.upload_url_generated_at,
            file_size_bytes: current.file_size_bytes,
            tagged_at: current.tagged_at,
            embedded_at: current.embedded_at,
            segmented_at: current.segmented_at,
            tracked_at: current.tracked_at,
            thumbnail_file_path: current.thumbnail_file_path,
            thumbnail_generated_at: current.thumbnail_generated_at,
            proxy_file_path: current.proxy_file_path,
            proxy_generated_at: current.proxy_generated_at,
            lifecycle: current.lifecycle,
            lifecycle_changed_at: current.lifecycle_changed_at,
            lifecycle_changed_by: current.lifecycle_changed_by,
            lifecycle_reason: current.lifecycle_reason,
        }
    }
}

impl Artifact {
    pub fn new(
        file_path: String,
        session_id: Option<i64>,
        device_id: i64,
        modality: Option<String>,
        timestamp_observation: Option<String>,
    ) -> Self {
        use chrono::Utc;
        Self {
            id: None,
            created_at: None,
            file_path,
            session_id,
            timestamp_observation,
            modality,
            source: None,
            device_id,
            updated_at: None,
            timestamp_observation_end: Utc::now().to_rfc3339(),
            file_size_bytes: None,
            tagged_at: None,
            embedded_at: None,
            segmented_at: None,
            tracked_at: None,
            thumbnail_file_path: None,
            thumbnail_generated_at: None,
            proxy_file_path: None,
            proxy_generated_at: None,
            processing_blocked_at: None,
            processing_blocked_reason: None,
            lifecycle: EntityLifecycle::Active,
            lifecycle_changed_at: Some(Utc::now().to_rfc3339()),
            lifecycle_changed_by: None,
            lifecycle_reason: None,
        }
    }
}

impl ArtifactLocal {
    pub fn new(
        file_path: String,
        session_id: Option<i64>,
        device_id: i64,
        modality: Option<String>,
        timestamp_observation: Option<String>,
    ) -> Self {
        use chrono::Utc;
        Self {
            id: None,
            id_local: None,
            ancestor_id_local: None,
            created_at: None,
            file_path,
            session_id,
            timestamp_observation,
            modality,
            source: None,
            device_id,
            updated_at: None,
            timestamp_observation_end: Utc::now().to_rfc3339(),
            has_uploaded_file_to_storage: false,
            upload_url: None,
            upload_url_generated_at: None,
            file_size_bytes: None,
            tagged_at: None,
            embedded_at: None,
            segmented_at: None,
            tracked_at: None,
            thumbnail_file_path: None,
            thumbnail_generated_at: None,
            proxy_file_path: None,
            proxy_generated_at: None,
            lifecycle: EntityLifecycle::Active,
            lifecycle_changed_at: Utc::now().to_rfc3339(),
            lifecycle_changed_by: None,
            lifecycle_reason: None,
        }
    }

    pub fn mark_file_uploaded(&mut self) {
        self.has_uploaded_file_to_storage = true;
    }

    pub fn mark_file_not_uploaded(&mut self) {
        self.has_uploaded_file_to_storage = false;
    }

    pub fn is_file_uploaded(&self) -> bool {
        self.has_uploaded_file_to_storage
    }

    pub fn needs_file_upload(&self) -> bool {
        !self.has_uploaded_file_to_storage
    }
}