Skip to main content

rskit_storage/store/
model.rs

1use std::collections::HashMap;
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6/// Default MIME type used when storage metadata does not provide one.
7pub const DEFAULT_CONTENT_TYPE: &str = "application/octet-stream";
8
9/// Metadata about a stored file.
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct StoredFile {
12    /// Storage key (path/identifier).
13    pub key: String,
14    /// File size in bytes.
15    pub size: u64,
16    /// MIME content type.
17    pub content_type: String,
18    /// When the file was stored.
19    pub stored_at: DateTime<Utc>,
20    /// Arbitrary metadata.
21    pub metadata: HashMap<String, String>,
22}
23
24impl StoredFile {
25    /// Create stored-file metadata with default storage timestamp and empty user metadata.
26    #[must_use]
27    pub fn new(key: impl Into<String>, size: u64, content_type: Option<&str>) -> Self {
28        Self {
29            key: key.into(),
30            size,
31            content_type: content_type_or_default(content_type).to_string(),
32            stored_at: Utc::now(),
33            metadata: HashMap::new(),
34        }
35    }
36
37    /// Attach backend metadata to this stored-file descriptor.
38    #[must_use]
39    pub fn with_metadata(mut self, metadata: HashMap<String, String>) -> Self {
40        self.metadata = metadata;
41        self
42    }
43
44    /// Override the storage timestamp.
45    #[must_use]
46    pub fn with_stored_at(mut self, stored_at: DateTime<Utc>) -> Self {
47        self.stored_at = stored_at;
48        self
49    }
50}
51
52/// Return the provided content type or the storage default.
53#[must_use]
54pub fn content_type_or_default(content_type: Option<&str>) -> &str {
55    content_type
56        .map(str::trim)
57        .filter(|value| !value.is_empty())
58        .unwrap_or(DEFAULT_CONTENT_TYPE)
59}