fiberplane_models/
lib.rs

1/*!
2# Fiberplane Models
3
4> Core Models used across Fiberplane
5
6This crate contains a collection of models that are used across the Fiberplane
7products, including but not limited to:
8
9- Notebooks
10  - Notebook Cells
11  - Notebook Operations
12- Providers
13  - Provider Schemas
14- Comments
15- Rich-Text Formatting
16- Templates
17- Views
18- Workspaces
19
20*/
21
22use serde::de::{Error, Unexpected, Visitor};
23use serde::{Deserialize, Deserializer};
24use std::fmt;
25
26pub mod blobs;
27pub mod comments;
28pub mod data_sources;
29pub mod events;
30pub mod files;
31pub mod formatting;
32pub mod labels;
33pub mod names;
34pub mod notebooks;
35pub mod providers;
36pub mod proxies;
37pub mod query_data;
38pub mod realtime;
39pub mod snippets;
40pub mod sorting;
41pub mod templates;
42pub mod timestamps;
43pub mod tokens;
44pub mod users;
45pub mod utils;
46pub mod views;
47pub mod workspaces;
48
49fn debug_print_bytes(bytes: impl AsRef<[u8]>) -> String {
50    let bytes = bytes.as_ref();
51    if bytes.len() > 100 {
52        format!("{}...", String::from_utf8_lossy(&bytes[..100]))
53    } else {
54        String::from_utf8_lossy(bytes).to_string()
55    }
56}
57
58/// Any value that is present is considered Some value, including null
59// https://github.com/serde-rs/serde/issues/984#issuecomment-314143738
60pub(crate) fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
61where
62    T: Deserialize<'de>,
63    D: Deserializer<'de>,
64{
65    Deserialize::deserialize(deserializer).map(Some)
66}
67
68// workaround for "invalid type: string "1", expected u32" bug in query string:
69// - https://linear.app/fiberplane/issue/FP-3066#comment-59e010ae
70// - https://github.com/tokio-rs/axum/discussions/1359
71// use on struct like this: #[serde(deserialize_with = "crate::deserialize_u32")]
72pub(crate) fn deserialize_u32<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
73    deserializer.deserialize_str(U32Visitor)
74}
75
76struct U32Visitor;
77
78impl<'de> Visitor<'de> for U32Visitor {
79    type Value = u32;
80
81    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
82        formatter.write_str("an u32")
83    }
84
85    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
86    where
87        E: Error,
88    {
89        Ok(v)
90    }
91
92    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
93    where
94        E: Error,
95    {
96        v.parse()
97            .map_err(|_| Error::invalid_type(Unexpected::Str(v), &self))
98    }
99
100    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
101    where
102        E: Error,
103    {
104        v.parse()
105            .map_err(|_| Error::invalid_type(Unexpected::Str(v), &self))
106    }
107
108    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
109    where
110        E: Error,
111    {
112        v.parse()
113            .map_err(|_| Error::invalid_type(Unexpected::Str(&v), &self))
114    }
115}