ferrin_spec/shared/
file_data.rs1use bytes::Bytes;
4use serde::Deserialize;
5use serde::Serialize;
6use url::Url;
7
8use super::ProviderReference;
9use super::base64_bytes;
10
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19#[serde(tag = "type", rename_all = "kebab-case")]
20#[non_exhaustive]
21pub enum FileData {
22 #[serde(rename = "data")]
24 Bytes {
25 #[serde(with = "base64_bytes")]
27 data: Bytes,
28 },
29 Url {
31 url: Url,
33 },
34 Reference {
36 reference: ProviderReference,
38 },
39 Text {
41 text: String,
43 },
44}
45
46impl FileData {
47 #[must_use]
49 pub fn bytes(data: impl Into<Bytes>) -> Self {
50 Self::Bytes { data: data.into() }
51 }
52
53 pub fn from_base64(text: &str) -> Result<Self, base64::DecodeError> {
59 base64_bytes::decode(text).map(|data| Self::Bytes { data })
60 }
61
62 #[must_use]
64 pub fn url(url: Url) -> Self {
65 Self::Url { url }
66 }
67
68 #[must_use]
70 pub fn reference(provider: impl Into<String>, id: impl Into<String>) -> Self {
71 let mut map = ProviderReference::new();
72 map.insert(provider.into(), id.into());
73 Self::Reference { reference: map }
74 }
75
76 #[must_use]
78 pub fn text(text: impl Into<String>) -> Self {
79 Self::Text { text: text.into() }
80 }
81
82 #[must_use]
84 pub fn as_bytes(&self) -> Option<&Bytes> {
85 match self {
86 Self::Bytes { data } => Some(data),
87 Self::Url { .. } | Self::Reference { .. } | Self::Text { .. } => None,
88 }
89 }
90
91 #[must_use]
93 pub fn as_url(&self) -> Option<&Url> {
94 match self {
95 Self::Url { url } => Some(url),
96 Self::Bytes { .. } | Self::Reference { .. } | Self::Text { .. } => None,
97 }
98 }
99
100 #[must_use]
102 pub fn as_reference(&self) -> Option<&ProviderReference> {
103 match self {
104 Self::Reference { reference } => Some(reference),
105 Self::Bytes { .. } | Self::Url { .. } | Self::Text { .. } => None,
106 }
107 }
108
109 #[must_use]
111 pub fn as_text(&self) -> Option<&str> {
112 match self {
113 Self::Text { text } => Some(text),
114 Self::Bytes { .. } | Self::Url { .. } | Self::Reference { .. } => None,
115 }
116 }
117
118 #[must_use]
120 pub fn to_base64(&self) -> Option<String> {
121 self.as_bytes().map(|bytes| base64_bytes::encode(bytes))
122 }
123}
124
125impl From<Bytes> for FileData {
126 fn from(data: Bytes) -> Self {
127 Self::Bytes { data }
128 }
129}
130
131impl From<Vec<u8>> for FileData {
132 fn from(bytes: Vec<u8>) -> Self {
133 Self::Bytes {
134 data: Bytes::from(bytes),
135 }
136 }
137}
138
139impl From<Url> for FileData {
140 fn from(url: Url) -> Self {
141 Self::Url { url }
142 }
143}
144
145impl From<ProviderReference> for FileData {
146 fn from(reference: ProviderReference) -> Self {
147 Self::Reference { reference }
148 }
149}