fiberplane_models/
data_sources.rs

1use crate::{names::Name, providers::Error};
2use base64uuid::Base64Uuid;
3#[cfg(feature = "fp-bindgen")]
4use fp_bindgen::prelude::Serializable;
5use serde::{Deserialize, Serialize};
6use serde_json::{Map, Value};
7use std::collections::BTreeMap;
8use strum_macros::Display;
9use time::{serde::rfc3339, OffsetDateTime};
10use typed_builder::TypedBuilder;
11
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, TypedBuilder)]
13#[non_exhaustive]
14#[serde(rename_all = "camelCase")]
15pub struct DataSource {
16    pub name: Name,
17    #[builder(default)]
18    pub proxy_name: Option<Name>,
19    pub id: Base64Uuid,
20    pub provider_type: String,
21    #[builder(default)]
22    #[serde(default)]
23    pub protocol_version: u8,
24    #[builder(default)]
25    #[serde(default, skip_serializing_if = "Option::is_none")]
26    pub description: Option<String>,
27    #[builder(default)]
28    #[serde(default, skip_serializing_if = "Option::is_none")]
29    pub config: Option<Map<String, Value>>,
30    #[builder(default)]
31    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
32    pub status: Option<DataSourceStatus>,
33    #[builder(setter(into))]
34    #[serde(with = "rfc3339")]
35    pub created_at: OffsetDateTime,
36    #[builder(setter(into))]
37    #[serde(with = "rfc3339")]
38    pub updated_at: OffsetDateTime,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Display)]
42#[cfg_attr(
43    feature = "fp-bindgen",
44    derive(Serializable),
45    fp(rust_module = "fiberplane_models::data_sources")
46)]
47#[non_exhaustive]
48#[serde(tag = "status", content = "error", rename_all = "snake_case")]
49pub enum DataSourceStatus {
50    Connected,
51    Error(Error),
52}
53
54#[derive(Debug, Deserialize, Serialize, Clone, TypedBuilder)]
55#[non_exhaustive]
56#[serde(rename_all = "camelCase")]
57pub struct NewDataSource {
58    pub name: Name,
59    #[builder(setter(into))]
60    pub provider_type: String,
61    #[builder(default)]
62    #[serde(default)]
63    pub protocol_version: u8,
64    #[builder(default, setter(into))]
65    pub description: Option<String>,
66    #[builder(default, setter(into))]
67    pub config: Map<String, Value>,
68}
69
70#[derive(Debug, Deserialize, Serialize, Clone, TypedBuilder)]
71#[non_exhaustive]
72#[serde(rename_all = "camelCase")]
73pub struct UpdateDataSource {
74    pub description: Option<String>,
75    pub config: Option<Map<String, Value>>,
76}
77
78#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, TypedBuilder)]
79#[cfg_attr(
80    feature = "fp-bindgen",
81    derive(Serializable),
82    fp(rust_module = "fiberplane_models::data_sources")
83)]
84#[non_exhaustive]
85#[serde(rename_all = "camelCase")]
86pub struct SelectedDataSource {
87    /// The name of the selected data source
88    pub name: Name,
89
90    /// If this is a proxy data source, the name of the proxy
91    #[builder(default, setter(strip_option))]
92    #[serde(default, skip_serializing_if = "Option::is_none")]
93    pub proxy_name: Option<Name>,
94}
95
96pub type ProviderType = String;
97
98/// This is a map from provider type to the selected data source for that type.
99pub type SelectedDataSources = BTreeMap<ProviderType, SelectedDataSource>;
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use pretty_assertions::assert_eq;
105    use serde_json::json;
106
107    #[test]
108    fn status_serialization() {
109        let serialized = serde_json::to_value(&DataSourceStatus::Connected).unwrap();
110        assert_eq!(serialized, json!({"status":"connected"}));
111
112        assert_eq!(
113            serde_json::to_value(&DataSourceStatus::Error(Error::NotFound)).unwrap(),
114            json!({
115                "status": "error",
116                "error": {
117                    "type": "not_found",
118                }
119            })
120        );
121    }
122}