phonograph/phono-server/src/presentation_form.rs

61 lines
2.1 KiB
Rust
Raw Normal View History

use std::iter::zip;
use phono_models::presentation::{
2025-11-11 06:42:54 +00:00
DropdownOption, Presentation, PresentationDiscriminants, RFC_3339_S, TextInputMode,
};
use serde::Deserialize;
use crate::errors::AppError;
/// A subset of an HTTP form that represents a [`Presentation`] in its component
/// parts. It may be merged into a larger HTTP form using `serde(flatten)`.
#[derive(Clone, Debug, Deserialize)]
pub(crate) struct PresentationForm {
pub(crate) presentation_tag: String,
#[serde(default)]
pub(crate) dropdown_option_colors: Vec<String>,
#[serde(default)]
pub(crate) dropdown_option_values: Vec<String>,
#[serde(default)]
pub(crate) text_input_mode: String,
#[serde(default)]
pub(crate) timestamp_format: String,
}
impl TryFrom<PresentationForm> for Presentation {
type Error = AppError;
fn try_from(form_value: PresentationForm) -> Result<Self, Self::Error> {
2025-11-11 06:42:54 +00:00
let discriminant =
PresentationDiscriminants::try_from(form_value.presentation_tag.as_str())?;
Ok(match discriminant {
PresentationDiscriminants::Dropdown => Presentation::Dropdown {
allow_custom: false,
options: zip(
form_value.dropdown_option_colors,
form_value.dropdown_option_values,
)
.map(|(color, value)| DropdownOption { color, value })
.collect(),
},
2025-11-11 06:42:54 +00:00
PresentationDiscriminants::Numeric => Presentation::Numeric {},
PresentationDiscriminants::Text => Presentation::Text {
input_mode: TextInputMode::try_from(form_value.text_input_mode.as_str())?,
},
2025-11-11 06:42:54 +00:00
PresentationDiscriminants::Timestamp => Presentation::Timestamp {
format: if form_value.timestamp_format.is_empty() {
RFC_3339_S.to_owned()
} else {
form_value.timestamp_format
},
utc: true,
},
2025-11-11 06:42:54 +00:00
PresentationDiscriminants::Uuid => Presentation::Uuid {},
})
}
}