scalar_cms/
lib.rs

1use std::{
2    fmt::Debug,
3    ops::{Deref, DerefMut},
4};
5
6pub use scalar_derive::{doc_enum, Document, EditorField, Enum};
7use serde::{Deserialize, Serialize};
8use ts_rs::TS;
9
10pub use chrono::{DateTime, Utc};
11pub use nanoid::nanoid;
12
13pub use db::DatabaseConnection;
14
15pub mod db;
16pub mod editor_field;
17pub mod editor_type;
18pub mod internals;
19pub mod validations;
20
21pub use serde_json::Value;
22
23pub fn convert<T: Serialize>(value: T) -> Value {
24    serde_json::to_value(value).expect("this should never fail")
25}
26
27pub use editor_field::EditorField;
28pub use editor_type::EditorType;
29use validations::Validate;
30
31#[derive(Serialize, Deserialize)]
32pub struct MultiLine(String);
33#[derive(Serialize, Deserialize, Debug)]
34#[serde(transparent)]
35pub struct Markdown(String);
36
37impl Deref for MultiLine {
38    type Target = String;
39
40    fn deref(&self) -> &Self::Target {
41        &self.0
42    }
43}
44impl DerefMut for MultiLine {
45    fn deref_mut(&mut self) -> &mut Self::Target {
46        &mut self.0
47    }
48}
49
50impl Deref for Markdown {
51    type Target = String;
52
53    fn deref(&self) -> &Self::Target {
54        &self.0
55    }
56}
57impl DerefMut for Markdown {
58    fn deref_mut(&mut self) -> &mut Self::Target {
59        &mut self.0
60    }
61}
62
63#[derive(Serialize, TS)]
64pub struct Schema {
65    identifier: &'static str,
66    title: &'static str,
67    fields: Vec<EditorField>,
68}
69
70#[derive(Serialize, TS)]
71pub struct DocInfo {
72    pub identifier: &'static str,
73    pub title: &'static str,
74}
75
76pub trait Document: Validate {
77    fn identifier() -> &'static str;
78    fn title() -> &'static str;
79
80    fn fields() -> Vec<EditorField>;
81    fn schema() -> Schema {
82        Schema {
83            identifier: Self::identifier(),
84            title: Self::title(),
85            fields: Self::fields(),
86        }
87    }
88}
89
90#[derive(Serialize, Deserialize, Debug, TS)]
91#[ts(export, concrete(D = String))]
92pub struct Item<D> {
93    #[serde(rename = "__sc_id")]
94    pub id: String,
95    #[serde(rename = "__sc_created_at")]
96    pub created_at: DateTime<Utc>,
97    #[serde(rename = "__sc_modified_at")]
98    pub modified_at: DateTime<Utc>,
99    #[serde(rename = "__sc_published_at")]
100    pub published_at: Option<DateTime<Utc>>,
101    #[serde(rename = "content")]
102    #[ts(type = "any")]
103    pub inner: D,
104}
105
106impl<D: Document> Validate for Item<D> {
107    fn validate(&self) -> Result<(), validations::ValidationError> {
108        self.inner.validate()
109    }
110}