first using ndpc2 as preset collection [refs #19]
This commit is contained in:
parent
765bcc0697
commit
9283396661
11 changed files with 303 additions and 49 deletions
|
|
@ -2,11 +2,14 @@ use std::collections::HashMap;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
use serde::de::IntoDeserializer;
|
||||||
|
use serde::Serialize;
|
||||||
use sqlx::{Row, SqlitePool};
|
use sqlx::{Row, SqlitePool};
|
||||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||||
use utoipa::gen::serde_json;
|
use utoipa::gen::serde_json;
|
||||||
use sslo_lib::error::SsloError;
|
use sslo_lib::error::SsloError;
|
||||||
use sslo_lib::db::{IndexedDataRow, OrderBy, WhereFieldsEqual};
|
use sslo_lib::db::{IndexedDataRow, OrderBy, WhereFieldsEqual};
|
||||||
|
use sslo_lib::ndpc2::collection::NdpcCollection;
|
||||||
use sslo_lib::ndpc::collection::{Collection, CollectionLike};
|
use sslo_lib::ndpc::collection::{Collection, CollectionLike};
|
||||||
use crate::db2::configuration::ConfigurationDbData;
|
use crate::db2::configuration::ConfigurationDbData;
|
||||||
use crate::db2::{DatabaseManager, DatabaseManagerData};
|
use crate::db2::{DatabaseManager, DatabaseManagerData};
|
||||||
|
|
@ -196,7 +199,7 @@ impl PresetItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns a copy of the NDPC preset
|
/// returns a copy of the NDPC preset
|
||||||
pub fn npdc(&self) -> Pin<Box<dyn Future<Output = Box<CollPreset>> + Send + '_>> {
|
pub fn npdc(&self) -> Pin<Box<dyn Future<Output = CollPreset> + Send + '_>> {
|
||||||
|
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
|
|
||||||
|
|
@ -223,11 +226,7 @@ impl PresetItem {
|
||||||
None => {}
|
None => {}
|
||||||
Some(row) => match row.ndpc.as_ref() {
|
Some(row) => match row.ndpc.as_ref() {
|
||||||
None => {},
|
None => {},
|
||||||
Some(ndpc_str) => {
|
Some(ndpc_str) => ndpc.state_import_str(ndpc_str),
|
||||||
if let Err(e) = ndpc.state_import_json_str(&ndpc_str) {
|
|
||||||
log::error!("Failed applying ndpc string from database {}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +234,7 @@ impl PresetItem {
|
||||||
// link parent collection
|
// link parent collection
|
||||||
let parent = self.parent().await;
|
let parent = self.parent().await;
|
||||||
if let Some(parent) = parent {
|
if let Some(parent) = parent {
|
||||||
let pc: Box<dyn CollectionLike> = parent.npdc().await;
|
let pc: CollPreset = parent.npdc().await;
|
||||||
ndpc.derive_from(&pc);
|
ndpc.derive_from(&pc);
|
||||||
}
|
}
|
||||||
ndpc
|
ndpc
|
||||||
|
|
@ -243,12 +242,12 @@ impl PresetItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract values from the given ndpc object and store it into database
|
/// Extract values from the given ndpc object and store it into database
|
||||||
pub async fn ndpc_import(&self, ndpc: Box<CollPreset>) -> Result<(), SsloError> {
|
pub async fn ndpc_import(&self, ndpc: CollPreset) -> Result<(), SsloError> {
|
||||||
let mut item_data = self.0.write().await;
|
let mut item_data = self.0.write().await;
|
||||||
let pool = item_data.pool.clone();
|
let pool = item_data.pool.clone();
|
||||||
match item_data.row.as_mut() {
|
match item_data.row.as_mut() {
|
||||||
Some(row) => {
|
Some(row) => {
|
||||||
row.ndpc = Some(ndpc.state_export_json_str());
|
row.ndpc = Some(ndpc.state_export_str());
|
||||||
let res = row.upsert(&pool).await;
|
let res = row.upsert(&pool).await;
|
||||||
log::info!("Updating {}", row.display());
|
log::info!("Updating {}", row.display());
|
||||||
res
|
res
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use axum::extract::{Path, State};
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::response::{Html, Response};
|
use axum::response::{Html, Response};
|
||||||
use sslo_lib::html_modal::{Dialog, DialogButtonStyle};
|
use sslo_lib::html_modal::{Dialog, DialogButtonStyle};
|
||||||
use sslo_lib::ndpc::collection::CollectionLike;
|
use sslo_lib::ndpc2::collection::NdpcCollection;
|
||||||
use crate::app_state::AppState;
|
use crate::app_state::AppState;
|
||||||
use crate::db2::configuration::presets::{PresetItem, PresetItemOrder, PresetTable};
|
use crate::db2::configuration::presets::{PresetItem, PresetItemOrder, PresetTable};
|
||||||
use crate::http::HtmlTemplate;
|
use crate::http::HtmlTemplate;
|
||||||
|
|
@ -86,8 +86,8 @@ async fn generate_html(app_state: &AppState,
|
||||||
dia.add_button(DialogButtonStyle::Save, "Save Preset".to_string(), "savePreset".to_string());
|
dia.add_button(DialogButtonStyle::Save, "Save Preset".to_string(), "savePreset".to_string());
|
||||||
dia.add_button(DialogButtonStyle::Cancel, "Cancel Editing".to_string(), "cancelPresetEdit".to_string());
|
dia.add_button(DialogButtonStyle::Cancel, "Cancel Editing".to_string(), "cancelPresetEdit".to_string());
|
||||||
if let Some(preset) = &preset {
|
if let Some(preset) = &preset {
|
||||||
let coll: Box<dyn CollectionLike> = preset.npdc().await;
|
let coll = preset.npdc().await;
|
||||||
dia.push_form(&coll.html(""));
|
dia.push_form(&coll.html());
|
||||||
}
|
}
|
||||||
html.push_body(&dia.to_str());
|
html.push_body(&dia.to_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,18 @@ use axum::response::{IntoResponse, Response};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::task::id;
|
use tokio::task::id;
|
||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
use sslo_lib::ndpc::collection::{Collection, CollectionLike};
|
use sslo_lib::ndpc2::collection::{NdpcCollection, NdpcCollectionIO};
|
||||||
use sslo_lib::ndpc::parameter::{ParameterLike, StateIO};
|
|
||||||
use sslo_lib::rest_api::ErrorResponse;
|
use sslo_lib::rest_api::ErrorResponse;
|
||||||
use crate::app_state::AppState;
|
use crate::app_state::AppState;
|
||||||
use crate::db2::configuration::presets::PresetItem;
|
use crate::db2::configuration::presets::PresetItem;
|
||||||
use crate::http::http_user::HttpUserExtractor;
|
use crate::http::http_user::HttpUserExtractor;
|
||||||
use crate::ndpc::coll_preset::CollPreset;
|
|
||||||
|
|
||||||
#[derive(ToSchema)]
|
#[derive(ToSchema)]
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct PatchPresetRequest (Vec<StateIO>);
|
pub struct PatchPresetRequest {
|
||||||
|
ndpc: Option<NdpcCollectionIO>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(ToSchema)]
|
#[derive(ToSchema)]
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|
@ -84,7 +85,7 @@ pub async fn handler_get(State(app_state): State<AppState>,
|
||||||
let resp = GetPresetResponse {
|
let resp = GetPresetResponse {
|
||||||
id: preset.id().await,
|
id: preset.id().await,
|
||||||
name: preset.name().await,
|
name: preset.name().await,
|
||||||
html_edit: collection.html("PresetCollection"),
|
html_edit: collection.html(),
|
||||||
html_view: collection.html_view(),
|
html_view: collection.html_view(),
|
||||||
};
|
};
|
||||||
(StatusCode::OK, Json(resp)).into_response()
|
(StatusCode::OK, Json(resp)).into_response()
|
||||||
|
|
@ -106,7 +107,7 @@ pub async fn handler_get(State(app_state): State<AppState>,
|
||||||
pub async fn handler_patch(State(app_state): State<AppState>,
|
pub async fn handler_patch(State(app_state): State<AppState>,
|
||||||
HttpUserExtractor(http_user): HttpUserExtractor,
|
HttpUserExtractor(http_user): HttpUserExtractor,
|
||||||
Path(id): Path<i64>,
|
Path(id): Path<i64>,
|
||||||
Json(parameters): Json<PatchPresetRequest>,
|
Json(request): Json<PatchPresetRequest>,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
|
|
||||||
// get basics
|
// get basics
|
||||||
|
|
@ -129,7 +130,10 @@ pub async fn handler_patch(State(app_state): State<AppState>,
|
||||||
|
|
||||||
// patch collection
|
// patch collection
|
||||||
let mut collection = preset.npdc().await;
|
let mut collection = preset.npdc().await;
|
||||||
collection.state_import(parameters.0);
|
if let Some(ndpc_io) = request.ndpc {
|
||||||
|
collection.state_import(&ndpc_io);
|
||||||
|
}
|
||||||
|
// collection.state_import(&request);
|
||||||
|
|
||||||
// save to preset
|
// save to preset
|
||||||
match preset.ndpc_import(collection).await {
|
match preset.ndpc_import(collection).await {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use axum::response::Html;
|
use axum::response::Html;
|
||||||
|
use sslo_lib::ndpc2::collection::NdpcCollection;
|
||||||
|
use sslo_lib::ndpc2::parameter::{NdpcParameter, NdpcParameterMetaData};
|
||||||
use sslo_lib::ndpc::collection::{Collection, CollectionLike, CollectionMetaData};
|
use sslo_lib::ndpc::collection::{Collection, CollectionLike, CollectionMetaData};
|
||||||
use sslo_lib::ndpc::param_enum_single::ParamEnumSingle;
|
use sslo_lib::ndpc::param_enum_single::ParamEnumSingle;
|
||||||
use sslo_lib::ndpc::param_i64::ParamI64;
|
use sslo_lib::ndpc::param_i64::ParamI64;
|
||||||
|
|
@ -189,35 +191,22 @@ macro_rules! make_weather {
|
||||||
|
|
||||||
|
|
||||||
pub struct CollPreset {
|
pub struct CollPreset {
|
||||||
meta: CollectionMetaData,
|
meta: NdpcParameterMetaData,
|
||||||
}
|
label: String,
|
||||||
|
|
||||||
impl CollectionLike for CollPreset {
|
|
||||||
fn meta(&self) -> &CollectionMetaData { &self.meta }
|
|
||||||
fn meta_mut(&mut self) -> &mut CollectionMetaData { &mut self.meta}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CollPreset {
|
impl CollPreset {
|
||||||
pub async fn new(db: Option<DatabaseManager>, label: String) -> Box<Self> {
|
|
||||||
|
|
||||||
// instantiate the collection
|
pub async fn new(db: Option<DatabaseManager>, label: String) -> Self {
|
||||||
let mut preset = Box::new(Self {
|
Self {
|
||||||
meta: CollectionMetaData::new("preset", label),
|
meta: NdpcParameterMetaData::new(),
|
||||||
});
|
label,
|
||||||
|
}
|
||||||
preset.add_collection(get_general());
|
|
||||||
preset.add_collection(get_rating());
|
|
||||||
preset.add_collection(get_server());
|
|
||||||
preset.add_collection(get_session());
|
|
||||||
preset.add_collection(get_car_classes(db).await);
|
|
||||||
preset.add_collection(get_weather());
|
|
||||||
|
|
||||||
preset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn html_view(&self) -> String {
|
pub fn html_view(&self) -> String {
|
||||||
let mut html = "<div class=\"NdpcCollPresetView\">".to_string();
|
let mut html = "<div class=\"NdpcCollPresetView\">".to_string();
|
||||||
html += &format!("<div class=\"NdpcCollPresetViewTitle\">{}</div>", self.meta.label);
|
html += &format!("<div class=\"NdpcCollPresetViewTitle\">{}</div>", self.label);
|
||||||
|
|
||||||
// general
|
// general
|
||||||
html+= "<div>";
|
html+= "<div>";
|
||||||
|
|
@ -229,6 +218,27 @@ impl CollPreset {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NdpcCollection for CollPreset {
|
||||||
|
fn ucid(&self) -> &'static str { "preset" }
|
||||||
|
fn label(&self) -> &str { &self.label }
|
||||||
|
|
||||||
|
fn child_parameters(&self) -> Vec<&dyn NdpcParameter> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn child_parameters_mut(&mut self) -> Vec<&mut dyn NdpcParameter> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn child_collections(&self) -> Vec<&dyn NdpcCollection> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn child_collections_mut(&mut self) -> Vec<&mut dyn NdpcCollection> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async fn get_car_classes(db: Option<DatabaseManager>) -> Box<Collection> {
|
async fn get_car_classes(db: Option<DatabaseManager>) -> Box<Collection> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use sslo_lib::error::SsloError;
|
use sslo_lib::error::SsloError;
|
||||||
|
use sslo_lib::ndpc2::parameter::{NdpcParameter, NdpcParameterMetaData};
|
||||||
use sslo_lib::ndpc::parameter::{ParameterLike, ParameterMetaData};
|
use sslo_lib::ndpc::parameter::{ParameterLike, ParameterMetaData};
|
||||||
use crate::db2::content::classes::ClassesTable;
|
use crate::db2::content::classes::ClassesTable;
|
||||||
use crate::db2::DatabaseManager;
|
use crate::db2::DatabaseManager;
|
||||||
|
|
@ -92,4 +93,41 @@ impl ParameterLike for ParamCarClasses {
|
||||||
}
|
}
|
||||||
Err(SsloError::NdpcValueMismatch(self.meta.upid().to_string(), value))
|
Err(SsloError::NdpcValueMismatch(self.meta.upid().to_string(), value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl NdpcParameter for ParamCarClasses {
|
||||||
|
//
|
||||||
|
// fn upid(&self) -> &'static str { self.upid}
|
||||||
|
// fn meta(&self) -> &NdpcParameterMetaData {&self.meta}
|
||||||
|
// fn meta_mut(&mut self) -> &mut NdpcParameterMetaData {&mut self.meta}
|
||||||
|
// fn label(&self) -> &str { "Car Class" }
|
||||||
|
// fn description(&self) -> &str {"Select here a car class to drive"}
|
||||||
|
// fn unit(&self) -> Option<&str> {None}
|
||||||
|
//
|
||||||
|
// fn html_input(&self) -> String {
|
||||||
|
//
|
||||||
|
// let options: Vec<String> = self.classes.0.iter()
|
||||||
|
// .map(|item| {
|
||||||
|
// let selected = match item.0 == self.selected_class {true => " selected=\"true\"", false => ""};
|
||||||
|
// format!("<option value=\"{}\"{}/>{}</option>", item.0, selected, item.1)
|
||||||
|
// }).collect();
|
||||||
|
//
|
||||||
|
// format!("<select>{}</select>", options.join(""))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn value_from_string(&mut self, value: &str) -> Result<(), SsloError> {
|
||||||
|
// match value.parse::<i64>() {
|
||||||
|
// Ok(mut value) => {
|
||||||
|
// self.selected_class = value;
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// Err(e) => {
|
||||||
|
// return Err(SsloError::NdpcValueMismatch(self.upid().to_string(), value.to_string()))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fn value2str(&self) -> String {
|
||||||
|
// self.selected_class.to_string()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
pub mod collection;
|
pub mod collection;
|
||||||
pub mod parameter;
|
pub mod parameter;
|
||||||
|
mod param_str;
|
||||||
|
mod param_i64;
|
||||||
|
mod param_enum;
|
||||||
|
|
||||||
use crate::error::SsloError;
|
use crate::error::SsloError;
|
||||||
use crate::ndpc2::parameter::{NdpcParaMetaData, NdpcParameter, NdpcParameterIO};
|
use crate::ndpc2::parameter::{NdpcParameterMetaData, NdpcParameter, NdpcParameterIO};
|
||||||
|
|
||||||
struct Parameter1 {
|
struct Parameter1 {
|
||||||
meta: NdpcParaMetaData,
|
meta: NdpcParameterMetaData,
|
||||||
value: String,
|
value: String,
|
||||||
}
|
}
|
||||||
impl NdpcParameter for Parameter1 {
|
impl NdpcParameter for Parameter1 {
|
||||||
|
|
@ -13,8 +16,8 @@ impl NdpcParameter for Parameter1 {
|
||||||
fn label(&self) -> &str {"Parameter 1"}
|
fn label(&self) -> &str {"Parameter 1"}
|
||||||
fn description(&self) -> &str {"This is only for testing"}
|
fn description(&self) -> &str {"This is only for testing"}
|
||||||
fn unit(&self) -> Option<&str> {None}
|
fn unit(&self) -> Option<&str> {None}
|
||||||
fn meta(&self) -> &NdpcParaMetaData {&self.meta}
|
fn meta(&self) -> &NdpcParameterMetaData {&self.meta}
|
||||||
fn meta_mut(&mut self) -> &mut NdpcParaMetaData {&mut self.meta}
|
fn meta_mut(&mut self) -> &mut NdpcParameterMetaData {&mut self.meta}
|
||||||
|
|
||||||
fn value_from_string(&mut self, value: &str) -> Result<(), SsloError> {
|
fn value_from_string(&mut self, value: &str) -> Result<(), SsloError> {
|
||||||
self.value = value.to_string();
|
self.value = value.to_string();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use utoipa::gen::serde_json;
|
||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
use super::parameter::{NdpcParameter, NdpcParameterIO};
|
use super::parameter::{NdpcParameter, NdpcParameterIO};
|
||||||
|
|
||||||
|
|
@ -6,8 +7,10 @@ use super::parameter::{NdpcParameter, NdpcParameterIO};
|
||||||
#[derive(ToSchema)]
|
#[derive(ToSchema)]
|
||||||
pub struct NdpcCollectionIO {
|
pub struct NdpcCollectionIO {
|
||||||
ucid: String,
|
ucid: String,
|
||||||
|
child_parameters: Vec<NdpcParameterIO>,
|
||||||
|
|
||||||
|
#[schema(no_recursion)] // avoid recursion within utoipa
|
||||||
child_collections: Vec<NdpcCollectionIO>,
|
child_collections: Vec<NdpcCollectionIO>,
|
||||||
child_parameters: Vec<NdpcParameterIO>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NdpcCollection : Send {
|
pub trait NdpcCollection : Send {
|
||||||
|
|
@ -97,6 +100,21 @@ pub trait NdpcCollection : Send {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn state_export_str(&self) -> String {
|
||||||
|
serde_json::to_string(&self.state_export()).unwrap_or_else(|e| {
|
||||||
|
log::error!("Failed to serialize ucid={}: {}", self.ucid(), e);
|
||||||
|
return "".to_string();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn state_import_str(&mut self, string: &str) {
|
||||||
|
let io: NdpcCollectionIO = match serde_json::from_str(string) {
|
||||||
|
Ok(io) => io,
|
||||||
|
Err(e) => return,
|
||||||
|
};
|
||||||
|
self.state_import(&io);
|
||||||
|
}
|
||||||
|
|
||||||
fn state_import(&mut self, io: &NdpcCollectionIO) {
|
fn state_import(&mut self, io: &NdpcCollectionIO) {
|
||||||
debug_assert!(io.ucid == self.ucid());
|
debug_assert!(io.ucid == self.ucid());
|
||||||
|
|
||||||
|
|
|
||||||
63
sslo_lib/src/ndpc2/param_enum.rs
Normal file
63
sslo_lib/src/ndpc2/param_enum.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
use crate::error::SsloError;
|
||||||
|
use crate::ndpc2::parameter::{NdpcParameter, NdpcParameterMetaData};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub struct ParamEnumStaticStr {
|
||||||
|
upid: &'static str,
|
||||||
|
label: String,
|
||||||
|
description: String,
|
||||||
|
unit: Option<String>,
|
||||||
|
meta: NdpcParameterMetaData,
|
||||||
|
enum_items: Vec<&'static str>,
|
||||||
|
selected_item: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParamEnumStaticStr {
|
||||||
|
pub fn new(upid: &'static str, label: String, unit: Option<String>, enum_items: Vec<&'static str>, description: String) -> Self { Self {
|
||||||
|
upid,
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
unit,
|
||||||
|
meta: NdpcParameterMetaData::new(),
|
||||||
|
enum_items,
|
||||||
|
selected_item: 0,
|
||||||
|
} }
|
||||||
|
|
||||||
|
pub fn value(&self) -> &'static str { self.enum_items.get(self.selected_item).unwrap_or(&"") }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NdpcParameter for ParamEnumStaticStr {
|
||||||
|
fn upid(&self) -> &'static str { self.upid}
|
||||||
|
fn label(&self) -> &str { &self.label}
|
||||||
|
fn description(&self) -> &str { &self.description }
|
||||||
|
fn unit(&self) -> Option<&str> { match &self.unit {None=>None, Some(s)=>Some(s)} }
|
||||||
|
fn meta(&self) -> &NdpcParameterMetaData { &self.meta}
|
||||||
|
fn meta_mut(&mut self) -> &mut NdpcParameterMetaData { &mut self.meta }
|
||||||
|
|
||||||
|
fn value_from_string(&mut self, value: &str) -> Result<(), SsloError> {
|
||||||
|
|
||||||
|
match self.enum_items.iter().position(|&item| item == value) {
|
||||||
|
Some(pos) => {
|
||||||
|
self.selected_item = pos;
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
log::warn!("Cannot concert value={} to a valid enum item within upid={}", value, self.upid);
|
||||||
|
Err(SsloError::NdpcValueMismatch(self.upid.to_string(), value.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value2str(&self) -> String {
|
||||||
|
self.enum_items.get(self.selected_item).unwrap_or(&"").to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn html_input(&self) -> String {
|
||||||
|
let options: Vec<String> = self.enum_items.iter().enumerate().map(|(index, item)| {
|
||||||
|
let selected = match self.selected_item == index {true => " selected=\"true\"", false => ""};
|
||||||
|
format!("<option value=\"{}\"{}/>{}</option>", item, selected, item)
|
||||||
|
}).collect();
|
||||||
|
format!("<select>{}</select>", options.join(""))
|
||||||
|
}
|
||||||
|
}
|
||||||
65
sslo_lib/src/ndpc2/param_i64.rs
Normal file
65
sslo_lib/src/ndpc2/param_i64.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
use crate::error::SsloError;
|
||||||
|
use crate::ndpc2::parameter::{NdpcParameter, NdpcParameterMetaData};
|
||||||
|
|
||||||
|
pub struct ParamI64 {
|
||||||
|
upid: &'static str,
|
||||||
|
label: String,
|
||||||
|
description: String,
|
||||||
|
unit: Option<String>,
|
||||||
|
meta: NdpcParameterMetaData,
|
||||||
|
value: i64,
|
||||||
|
value_min: i64,
|
||||||
|
value_max: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParamI64 {
|
||||||
|
pub fn new(upid: &'static str, label: String, unit: Option<String>, default: i64, min: i64, max: i64, description: String) -> Self { Self {
|
||||||
|
upid,
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
unit,
|
||||||
|
meta: NdpcParameterMetaData::new(),
|
||||||
|
value: default,
|
||||||
|
value_min: min,
|
||||||
|
value_max: max,
|
||||||
|
} }
|
||||||
|
|
||||||
|
pub fn value(&self) -> i64 { self.value }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NdpcParameter for ParamI64 {
|
||||||
|
fn upid(&self) -> &'static str { self.upid}
|
||||||
|
fn label(&self) -> &str { &self.label}
|
||||||
|
fn description(&self) -> &str { &self.description }
|
||||||
|
fn unit(&self) -> Option<&str> { match &self.unit {None=>None, Some(s)=>Some(s)} }
|
||||||
|
fn meta(&self) -> &NdpcParameterMetaData { &self.meta}
|
||||||
|
fn meta_mut(&mut self) -> &mut NdpcParameterMetaData { &mut self.meta }
|
||||||
|
|
||||||
|
fn value_from_string(&mut self, value: &str) -> Result<(), SsloError> {
|
||||||
|
match value.parse::<i64>() {
|
||||||
|
Ok(mut value) => {
|
||||||
|
if value < self.value_min {
|
||||||
|
log::warn!("Clipping value={} to allowed minimum={} for upid={}", value, self.value_min, self.upid);
|
||||||
|
value = self.value_min;
|
||||||
|
} else if value > self.value_max {
|
||||||
|
log::warn!("Clipping value={} to allowed maximum={} for upid={}", value, self.value_max, self.upid);
|
||||||
|
value = self.value_max;
|
||||||
|
}
|
||||||
|
self.value = value; Ok(())
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
Err(SsloError::NdpcValueMismatch(self.upid.to_string(), value.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value2str(&self) -> String {
|
||||||
|
self.value.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn html_input(&self) -> String {
|
||||||
|
format!("<input type=\"number\" value=\"{}\" min=\"{}\" max=\"{}\"/>",
|
||||||
|
self.value, self.value_min, self.value_max,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
46
sslo_lib/src/ndpc2/param_str.rs
Normal file
46
sslo_lib/src/ndpc2/param_str.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
use crate::error::SsloError;
|
||||||
|
use crate::ndpc2::parameter::{NdpcParameter, NdpcParameterMetaData};
|
||||||
|
|
||||||
|
pub struct ParamString {
|
||||||
|
upid: &'static str,
|
||||||
|
label: String,
|
||||||
|
description: String,
|
||||||
|
unit: Option<String>,
|
||||||
|
meta: NdpcParameterMetaData,
|
||||||
|
value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParamString {
|
||||||
|
pub fn new(upid: &'static str, label: String, unit: Option<String>, default: String, description: String) -> Self { Self {
|
||||||
|
upid,
|
||||||
|
label,
|
||||||
|
description,
|
||||||
|
unit,
|
||||||
|
meta: NdpcParameterMetaData::new(),
|
||||||
|
value: default,
|
||||||
|
} }
|
||||||
|
|
||||||
|
pub fn value(&self) -> &str { &self.value }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NdpcParameter for ParamString {
|
||||||
|
fn upid(&self) -> &'static str { self.upid}
|
||||||
|
fn label(&self) -> &str { &self.label}
|
||||||
|
fn description(&self) -> &str { &self.description }
|
||||||
|
fn unit(&self) -> Option<&str> { match &self.unit {None=>None, Some(s)=>Some(s)} }
|
||||||
|
fn meta(&self) -> &NdpcParameterMetaData { &self.meta}
|
||||||
|
fn meta_mut(&mut self) -> &mut NdpcParameterMetaData { &mut self.meta }
|
||||||
|
|
||||||
|
fn value_from_string(&mut self, value: &str) -> Result<(), SsloError> {
|
||||||
|
self.value = value.to_string();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value2str(&self) -> String {
|
||||||
|
self.value.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn html_input(&self) -> String {
|
||||||
|
format!("<input type=\"text\" value=\"{}\"/>", self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,12 +33,20 @@ pub struct NdpcParameterIO {
|
||||||
pub inheritance: Option<NdpcValueInheritance>,
|
pub inheritance: Option<NdpcValueInheritance>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NdpcParaMetaData {
|
pub struct NdpcParameterMetaData {
|
||||||
access: NdpcAccess,
|
access: NdpcAccess,
|
||||||
inheritance: NdpcValueInheritance,
|
inheritance: NdpcValueInheritance,
|
||||||
ancestor: Option<NdpcAncestor>
|
ancestor: Option<NdpcAncestor>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NdpcParameterMetaData {
|
||||||
|
pub fn new() -> Self { Self {
|
||||||
|
access: NdpcAccess::Locked,
|
||||||
|
inheritance: NdpcValueInheritance::Inherit,
|
||||||
|
ancestor: None,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait NdpcParameter : Send {
|
pub trait NdpcParameter : Send {
|
||||||
|
|
||||||
/// Every parameter shall have a unique parameter id
|
/// Every parameter shall have a unique parameter id
|
||||||
|
|
@ -53,8 +61,8 @@ pub trait NdpcParameter : Send {
|
||||||
/// An optional unit for the parameter
|
/// An optional unit for the parameter
|
||||||
fn unit(&self) -> Option<&str>;
|
fn unit(&self) -> Option<&str>;
|
||||||
|
|
||||||
fn meta(&self) -> &NdpcParaMetaData;
|
fn meta(&self) -> &NdpcParameterMetaData;
|
||||||
fn meta_mut(&mut self) -> &mut NdpcParaMetaData;
|
fn meta_mut(&mut self) -> &mut NdpcParameterMetaData;
|
||||||
|
|
||||||
/// Shall set the parameter value
|
/// Shall set the parameter value
|
||||||
/// If the passed value is invalid, the parameter shall remain unchanged
|
/// If the passed value is invalid, the parameter shall remain unchanged
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue