Implement Integral Data Types (#13)
**Rationale:** Integral Types were missing and are needed for Project Nautilus. **Changes:** - Implements Integral Data Types - u64 and i64 implemented through bigint Reviewed-on: #13 Co-authored-by: Sergey Savelyev <sergeysav.nn@gmail.com> Co-committed-by: Sergey Savelyev <sergeysav.nn@gmail.com>
This commit was merged in pull request #13.
This commit is contained in:
@@ -15,6 +15,7 @@ derive_more = { workspace = true, features = ["from"] }
|
||||
fern = { workspace = true, features = ["colored"] }
|
||||
futures-util = { workspace = true }
|
||||
log = { workspace = true }
|
||||
num-traits = { workspace = true }
|
||||
papaya = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -11,6 +11,7 @@ use api::messages::command::{Command, CommandDefinition, CommandHeader, CommandR
|
||||
use api::messages::ResponseMessage;
|
||||
use chrono::Utc;
|
||||
use log::error;
|
||||
use num_traits::FromPrimitive;
|
||||
use papaya::HashMap;
|
||||
use std::collections::HashMap as StdHashMap;
|
||||
use tokio::sync::oneshot;
|
||||
@@ -102,10 +103,34 @@ impl CommandManagementService {
|
||||
let Some(param_value) = parameters.get(¶meter.name) else {
|
||||
return Err(MisingParameter(parameter.name.clone()));
|
||||
};
|
||||
let Some(param_value) = (match parameter.data_type {
|
||||
DataType::Float32 => param_value.as_f64().map(|v| DataValue::Float32(v as f32)),
|
||||
DataType::Float64 => param_value.as_f64().map(DataValue::Float64),
|
||||
DataType::Boolean => param_value.as_bool().map(DataValue::Boolean),
|
||||
let Some(Some(param_value)) = (match parameter.data_type {
|
||||
DataType::Float32 => param_value
|
||||
.as_f64()
|
||||
.map(|v| Some(DataValue::Float32(v as f32))),
|
||||
DataType::Float64 => param_value.as_f64().map(DataValue::Float64).map(Some),
|
||||
DataType::Boolean => param_value.as_bool().map(DataValue::Boolean).map(Some),
|
||||
DataType::Int8 => param_value
|
||||
.as_i64()
|
||||
.map(|v| Some(DataValue::Int8(i8::from_i64(v)?))),
|
||||
DataType::Int16 => param_value
|
||||
.as_i64()
|
||||
.map(|v| Some(DataValue::Int16(i16::from_i64(v)?))),
|
||||
DataType::Int32 => param_value
|
||||
.as_i64()
|
||||
.map(|v| Some(DataValue::Int32(i32::from_i64(v)?))),
|
||||
DataType::Int64 => param_value.as_i64().map(|v| Some(DataValue::Int64(v))),
|
||||
DataType::Unsigned8 => param_value
|
||||
.as_u64()
|
||||
.map(|v| Some(DataValue::Unsigned8(u8::from_u64(v)?))),
|
||||
DataType::Unsigned16 => param_value
|
||||
.as_u64()
|
||||
.map(|v| Some(DataValue::Unsigned16(u16::from_u64(v)?))),
|
||||
DataType::Unsigned32 => param_value
|
||||
.as_u64()
|
||||
.map(|v| Some(DataValue::Unsigned32(u32::from_u64(v)?))),
|
||||
DataType::Unsigned64 => {
|
||||
param_value.as_u64().map(|v| Some(DataValue::Unsigned64(v)))
|
||||
}
|
||||
}) else {
|
||||
return Err(WrongParameterType {
|
||||
name: parameter.name.clone(),
|
||||
|
||||
@@ -29,6 +29,10 @@ pub(super) async fn get_one(
|
||||
name: web::Path<String>,
|
||||
) -> Result<impl Responder, HttpServerResultError> {
|
||||
Ok(web::Json(
|
||||
command_service.get_command_definition(&name.to_string()),
|
||||
command_service
|
||||
.get_command_definition(&name.to_string())
|
||||
.ok_or_else(|| HttpServerResultError::CmdNotFound {
|
||||
cmd: name.to_string(),
|
||||
})?,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ pub enum HttpServerResultError {
|
||||
PanelUuidNotFound { uuid: Uuid },
|
||||
#[error(transparent)]
|
||||
Command(#[from] crate::command::error::Error),
|
||||
#[error("Command Not Found: {cmd}")]
|
||||
CmdNotFound { cmd: String },
|
||||
}
|
||||
|
||||
impl ResponseError for HttpServerResultError {
|
||||
@@ -36,6 +38,7 @@ impl ResponseError for HttpServerResultError {
|
||||
HttpServerResultError::InternalError { .. } => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
HttpServerResultError::PanelUuidNotFound { .. } => StatusCode::NOT_FOUND,
|
||||
HttpServerResultError::Command(inner) => inner.status_code(),
|
||||
HttpServerResultError::CmdNotFound { .. } => StatusCode::NOT_FOUND,
|
||||
}
|
||||
}
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
|
||||
@@ -196,9 +196,17 @@ impl HistorySegmentFile {
|
||||
// Write all the values
|
||||
for value in &data.values {
|
||||
match value {
|
||||
DataValue::Float32(value) => file.write_data::<f32>(*value)?,
|
||||
DataValue::Float64(value) => file.write_data::<f64>(*value)?,
|
||||
DataValue::Boolean(value) => file.write_data::<bool>(*value)?,
|
||||
DataValue::Float32(value) => file.write_data(*value)?,
|
||||
DataValue::Float64(value) => file.write_data(*value)?,
|
||||
DataValue::Boolean(value) => file.write_data(*value)?,
|
||||
DataValue::Int8(value) => file.write_data(*value)?,
|
||||
DataValue::Int16(value) => file.write_data(*value)?,
|
||||
DataValue::Int32(value) => file.write_data(*value)?,
|
||||
DataValue::Int64(value) => file.write_data(*value)?,
|
||||
DataValue::Unsigned8(value) => file.write_data(*value)?,
|
||||
DataValue::Unsigned16(value) => file.write_data(*value)?,
|
||||
DataValue::Unsigned32(value) => file.write_data(*value)?,
|
||||
DataValue::Unsigned64(value) => file.write_data(*value)?,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,20 +340,20 @@ impl HistorySegmentFile {
|
||||
}
|
||||
|
||||
fn read_telemetry_item(&mut self, telemetry_data_type: DataType) -> anyhow::Result<DataValue> {
|
||||
match telemetry_data_type {
|
||||
DataType::Float32 => {
|
||||
self.file_position += 4;
|
||||
Ok(DataValue::Float32(self.file.read_data::<f32>()?))
|
||||
}
|
||||
DataType::Float64 => {
|
||||
self.file_position += 8;
|
||||
Ok(DataValue::Float64(self.file.read_data::<f64>()?))
|
||||
}
|
||||
DataType::Boolean => {
|
||||
self.file_position += 1;
|
||||
Ok(DataValue::Boolean(self.file.read_data::<bool>()?))
|
||||
}
|
||||
}
|
||||
self.file_position += telemetry_data_type.get_data_length() as i64;
|
||||
Ok(match telemetry_data_type {
|
||||
DataType::Float32 => self.file.read_data::<f32>()?.into(),
|
||||
DataType::Float64 => self.file.read_data::<f64>()?.into(),
|
||||
DataType::Boolean => self.file.read_data::<bool>()?.into(),
|
||||
DataType::Int8 => self.file.read_data::<i8>()?.into(),
|
||||
DataType::Int16 => self.file.read_data::<i16>()?.into(),
|
||||
DataType::Int32 => self.file.read_data::<i32>()?.into(),
|
||||
DataType::Int64 => self.file.read_data::<i64>()?.into(),
|
||||
DataType::Unsigned8 => self.file.read_data::<u8>()?.into(),
|
||||
DataType::Unsigned16 => self.file.read_data::<u16>()?.into(),
|
||||
DataType::Unsigned32 => self.file.read_data::<u32>()?.into(),
|
||||
DataType::Unsigned64 => self.file.read_data::<u64>()?.into(),
|
||||
})
|
||||
}
|
||||
|
||||
fn get_telemetry_item(
|
||||
@@ -353,11 +361,7 @@ impl HistorySegmentFile {
|
||||
index: u64,
|
||||
telemetry_data_type: DataType,
|
||||
) -> anyhow::Result<DataValue> {
|
||||
let item_length = match telemetry_data_type {
|
||||
DataType::Float32 => 4,
|
||||
DataType::Float64 => 8,
|
||||
DataType::Boolean => 1,
|
||||
};
|
||||
let item_length = telemetry_data_type.get_data_length();
|
||||
let desired_position =
|
||||
Self::HEADER_LENGTH + self.length * Self::TIMESTAMP_LENGTH + index * item_length;
|
||||
let seek_amount = desired_position as i64 - self.file_position;
|
||||
|
||||
@@ -3,8 +3,6 @@ use crate::telemetry::data_item::TelemetryDataItem;
|
||||
use crate::telemetry::definition::TelemetryDefinition;
|
||||
use crate::telemetry::history::{TelemetryHistory, TelemetryHistoryService};
|
||||
use anyhow::bail;
|
||||
use api::data_type::DataType;
|
||||
use api::data_value::DataValue;
|
||||
use api::messages::telemetry_definition::{
|
||||
TelemetryDefinitionRequest, TelemetryDefinitionResponse,
|
||||
};
|
||||
@@ -144,11 +142,7 @@ impl TelemetryManagementService {
|
||||
bail!("Telemetry Item Not Found");
|
||||
};
|
||||
|
||||
let expected_type = match &tlm_item.value {
|
||||
DataValue::Float32(_) => DataType::Float32,
|
||||
DataValue::Float64(_) => DataType::Float64,
|
||||
DataValue::Boolean(_) => DataType::Boolean,
|
||||
};
|
||||
let expected_type = tlm_item.value.to_data_type();
|
||||
if expected_type != tlm_data.data.definition.data_type {
|
||||
bail!("Data Type Mismatch");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user