refactor adapters into modular file structure
config-sqlite: split into repository/ (per entity) + serialization/ (per type) + error.rs http-api: split into dto/ (per resource) + routes/ (per resource) tcp-server: split into broadcaster, event_bus, server, error rss: split parser from adapter, external tests media: split error, external tests
This commit is contained in:
@@ -1,29 +1,10 @@
|
||||
pub mod error;
|
||||
mod serialization;
|
||||
mod repository;
|
||||
|
||||
use std::time::Duration;
|
||||
use sqlx::{SqlitePool, Row};
|
||||
use domain::{
|
||||
ConfigRepository,
|
||||
DataSource, DataSourceId, DataSourceConfig, DataSourceType,
|
||||
Layout, LayoutPreset, LayoutPresetId,
|
||||
WidgetConfig, WidgetId,
|
||||
};
|
||||
use serialization as ser;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SqliteConfigError {
|
||||
Sql(sqlx::Error),
|
||||
Serialization(String),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for SqliteConfigError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
SqliteConfigError::Sql(e) => write!(f, "sql: {e}"),
|
||||
SqliteConfigError::Serialization(e) => write!(f, "serialization: {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use error::SqliteConfigError;
|
||||
|
||||
pub struct SqliteConfigStore {
|
||||
pool: SqlitePool,
|
||||
@@ -77,186 +58,3 @@ impl SqliteConfigStore {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigRepository for SqliteConfigStore {
|
||||
type Error = SqliteConfigError;
|
||||
|
||||
async fn get_widget(&self, id: WidgetId) -> Result<Option<WidgetConfig>, Self::Error> {
|
||||
let row = sqlx::query("SELECT * FROM widgets WHERE id = ?")
|
||||
.bind(id as i64)
|
||||
.fetch_optional(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
match row {
|
||||
None => Ok(None),
|
||||
Some(row) => Ok(Some(ser::widget_from_row(&row)?)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_widgets(&self) -> Result<Vec<WidgetConfig>, Self::Error> {
|
||||
let rows = sqlx::query("SELECT * FROM widgets")
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
rows.iter().map(|r| ser::widget_from_row(r)).collect()
|
||||
}
|
||||
|
||||
async fn save_widget(&self, config: &WidgetConfig) -> Result<(), Self::Error> {
|
||||
let mappings_json = ser::mappings_to_json(&config.mappings)?;
|
||||
let hint_str = ser::display_hint_to_str(&config.display_hint);
|
||||
|
||||
sqlx::query(
|
||||
"INSERT OR REPLACE INTO widgets (id, name, display_hint, data_source_id, mappings, max_data_size)
|
||||
VALUES (?, ?, ?, ?, ?, ?)"
|
||||
)
|
||||
.bind(config.id as i64)
|
||||
.bind(&config.name)
|
||||
.bind(hint_str)
|
||||
.bind(config.data_source_id as i64)
|
||||
.bind(&mappings_json)
|
||||
.bind(config.max_data_size as i64)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_widget(&self, id: WidgetId) -> Result<(), Self::Error> {
|
||||
sqlx::query("DELETE FROM widgets WHERE id = ?")
|
||||
.bind(id as i64)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_data_source(&self, id: DataSourceId) -> Result<Option<DataSource>, Self::Error> {
|
||||
let row = sqlx::query("SELECT * FROM data_sources WHERE id = ?")
|
||||
.bind(id as i64)
|
||||
.fetch_optional(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
match row {
|
||||
None => Ok(None),
|
||||
Some(row) => Ok(Some(ser::data_source_from_row(&row)?)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_data_sources(&self) -> Result<Vec<DataSource>, Self::Error> {
|
||||
let rows = sqlx::query("SELECT * FROM data_sources")
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
rows.iter().map(|r| ser::data_source_from_row(r)).collect()
|
||||
}
|
||||
|
||||
async fn save_data_source(&self, source: &DataSource) -> Result<(), Self::Error> {
|
||||
let config_json = ser::data_source_config_to_json(&source.config)?;
|
||||
let type_str = ser::data_source_type_to_str(&source.source_type);
|
||||
|
||||
sqlx::query(
|
||||
"INSERT OR REPLACE INTO data_sources (id, name, source_type, poll_interval_secs, config)
|
||||
VALUES (?, ?, ?, ?, ?)"
|
||||
)
|
||||
.bind(source.id as i64)
|
||||
.bind(&source.name)
|
||||
.bind(type_str)
|
||||
.bind(source.poll_interval.as_secs() as i64)
|
||||
.bind(&config_json)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_data_source(&self, id: DataSourceId) -> Result<(), Self::Error> {
|
||||
sqlx::query("DELETE FROM data_sources WHERE id = ?")
|
||||
.bind(id as i64)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_layout(&self) -> Result<Option<Layout>, Self::Error> {
|
||||
let row = sqlx::query("SELECT data FROM layout WHERE id = 1")
|
||||
.fetch_optional(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
match row {
|
||||
None => Ok(None),
|
||||
Some(row) => {
|
||||
let json: String = row.get("data");
|
||||
Ok(Some(ser::layout_from_json(&json)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn save_layout(&self, layout: &Layout) -> Result<(), Self::Error> {
|
||||
let json = ser::layout_to_json(layout)?;
|
||||
|
||||
sqlx::query(
|
||||
"INSERT OR REPLACE INTO layout (id, data) VALUES (1, ?)"
|
||||
)
|
||||
.bind(&json)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_preset(&self, id: LayoutPresetId) -> Result<Option<LayoutPreset>, Self::Error> {
|
||||
let row = sqlx::query("SELECT * FROM presets WHERE id = ?")
|
||||
.bind(id as i64)
|
||||
.fetch_optional(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
match row {
|
||||
None => Ok(None),
|
||||
Some(row) => Ok(Some(ser::preset_from_row(&row)?)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_presets(&self) -> Result<Vec<LayoutPreset>, Self::Error> {
|
||||
let rows = sqlx::query("SELECT * FROM presets")
|
||||
.fetch_all(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
rows.iter().map(|r| ser::preset_from_row(r)).collect()
|
||||
}
|
||||
|
||||
async fn save_preset(&self, preset: &LayoutPreset) -> Result<(), Self::Error> {
|
||||
let layout_json = ser::layout_to_json(&preset.layout)?;
|
||||
|
||||
sqlx::query(
|
||||
"INSERT OR REPLACE INTO presets (id, name, layout_data) VALUES (?, ?, ?)"
|
||||
)
|
||||
.bind(preset.id as i64)
|
||||
.bind(&preset.name)
|
||||
.bind(&layout_json)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_preset(&self, id: LayoutPresetId) -> Result<(), Self::Error> {
|
||||
sqlx::query("DELETE FROM presets WHERE id = ?")
|
||||
.bind(id as i64)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(SqliteConfigError::Sql)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user