All checks were successful
continuous-integration/drone/push Build is passing
79 lines
2.1 KiB
Rust
79 lines
2.1 KiB
Rust
use super::section::SectionId;
|
|
use crate::schedule::Schedule;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::{sync::Arc, time::Duration};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ProgramItem {
|
|
pub section_id: SectionId,
|
|
#[serde(with = "crate::serde::duration")]
|
|
pub duration: Duration,
|
|
}
|
|
|
|
pub type ProgramSequence = Vec<ProgramItem>;
|
|
|
|
pub type ProgramId = u32;
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct Program {
|
|
pub id: ProgramId,
|
|
pub name: String,
|
|
pub sequence: ProgramSequence,
|
|
pub enabled: bool,
|
|
pub schedule: Schedule,
|
|
}
|
|
|
|
mod sql {
|
|
use super::{Program, ProgramSequence};
|
|
use crate::schedule::Schedule;
|
|
use rusqlite::{
|
|
types::{FromSql, FromSqlError, FromSqlResult, ValueRef},
|
|
Result as SqlResult, Row as SqlRow,
|
|
};
|
|
use serde::Deserialize;
|
|
|
|
struct SqlJson<T>(T);
|
|
|
|
impl<T> SqlJson<T> {
|
|
fn into_inner(self) -> T {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
impl<T> FromSql for SqlJson<T>
|
|
where
|
|
for<'de> T: Deserialize<'de>,
|
|
{
|
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
|
if let ValueRef::Text(text) = value {
|
|
let deser_value: T = serde_json::from_slice(text)
|
|
.map_err(|err| FromSqlError::Other(Box::new(err)))?;
|
|
Ok(SqlJson(deser_value))
|
|
} else {
|
|
Err(FromSqlError::InvalidType)
|
|
}
|
|
}
|
|
}
|
|
|
|
type SqlProgramSequence = SqlJson<ProgramSequence>;
|
|
type SqlSchedule = SqlJson<Schedule>;
|
|
|
|
impl Program {
|
|
pub fn from_sql<'a>(row: &SqlRow<'a>) -> SqlResult<Self> {
|
|
Ok(Self {
|
|
id: row.get(0)?,
|
|
name: row.get(1)?,
|
|
sequence: row.get::<_, SqlProgramSequence>(2)?.into_inner(),
|
|
enabled: row.get(3)?,
|
|
schedule: row.get::<_, SqlSchedule>(4)?.into_inner(),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
pub type ProgramRef = Arc<Program>;
|
|
|
|
pub type Programs = im::OrdMap<ProgramId, ProgramRef>;
|