From cca66b0cacf5ae763d7929f2d5b12405e581db50 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 28 Jun 2026 22:30:32 +0800 Subject: [PATCH] fix: fix kernel common module build issue --- kernel/lcrconn/src/common.rs | 428 +++++++++++++---------------- kernel/lcrconn/src/lib.rs | 2 +- kernel/lcrconn/src/query.rs | 6 +- kernel/lcrconn/src/resolver/bfs.rs | 6 +- kernel/lcrconn/src/resolver/lut.rs | 4 +- 5 files changed, 202 insertions(+), 244 deletions(-) diff --git a/kernel/lcrconn/src/common.rs b/kernel/lcrconn/src/common.rs index 0e36c2a..795b237 100644 --- a/kernel/lcrconn/src/common.rs +++ b/kernel/lcrconn/src/common.rs @@ -1,50 +1,6 @@ -use strum::IntoEnumIterator; use strum_macros::EnumIter; use thiserror::Error as TeError; -// /// The error thrown by LCR Connector. -// #[derive(Debug, TeError)] -// pub enum LcrConnError { -// #[error("Device value must be greater than 0")] -// InvalidDeviceValue, - -// #[error("Third device cannot exist without second device")] -// ThirdDeviceWithoutSecond, - -// #[error("No second device")] -// NoSecondDevice, - -// #[error("No third device")] -// NoThirdDevice, - -// #[error("Invalid value {0} in dataset")] -// InvalidDatasetValue(f64), - -// #[error("Unexpected empty string in dataset item")] -// EmptyDatasetItem, - -// #[error("Duplicate item {0} in standard value list")] -// DuplicateDatasetItem(String), - -// #[error("Empty standard value list is not allowed")] -// EmptyDataset, - -// #[error("Invalid value {0} for target value in request")] -// InvalidTargetValue(f64), - -// #[error("Invalid value {0} for tolerance in request")] -// InvalidTolerance(f64), - -// #[error("Too large or too less value {0} for response count limit in request")] -// InvalidCountLimit(usize), - -// #[error("Invalid human readable value: {0}")] -// InvalidHumanReadableValue(String), - -// #[error(transparent)] -// Io(#[from] std::io::Error), -// } - /// The kind of device. #[derive(Debug, Clone, Copy)] pub enum DeviceKind { @@ -79,6 +35,17 @@ impl JointKind { } } +/// Error occurs when manipulating [SubCircuit]. +#[derive(Debug, TeError)] +pub enum SubCircuitError { + #[error("given circuit device value {0} should greater than zero")] + BadDeviceValue(f64), + #[error("the previous computed circuit value {0} should greater than zero")] + BadPreviousValue(f64), + #[error("bad float point arithmetic")] + BadArithmetic, +} + /// The part of circuit composed of two devices and the joint kind. #[derive(Debug, Clone)] pub struct SubCircuit { @@ -90,55 +57,47 @@ pub struct SubCircuit { impl SubCircuit { /// Initialize subcircuit with given device value and joint kind. - /// - /// # Panics - /// - /// This function will panic if given device value is equal or lower than zero. - pub fn new(device_value: f64, joint_kind: JointKind) -> Self { - // Make sure value is greater than zero. - assert!( - device_value > 0f64, - "given device value {} should greater than zero", - device_value - ); - // Okey, build and return self - Self { - device_value, - joint_kind, + /// + /// The input device value should greater than zero, + /// otherwise an error will return. + pub fn new(device_value: f64, joint_kind: JointKind) -> Result { + if device_value > 0f64 { + Ok(Self { + device_value, + joint_kind, + }) + } else { + Err(SubCircuitError::BadDeviceValue(device_value)) } } - /// Compute the joint value. + /// Compute the joint value with given previous computed value and device kind. /// - /// # Arguments - /// - /// * `value` - The value computed from previous devices. - /// * `device_kind` - The kind of the device. - /// - /// # Returns - /// - /// The joint value computed. - /// - /// # Errors - /// - /// Returns [`LcrConnError::InvalidDeviceValue`] if any device value is not greater than 0. - pub fn compute(&self, value: f64, device_kind: DeviceKind) -> Result { - if self.device_value <= 0.0 || value <= 0.0 { - return Err(LcrConnError::InvalidDeviceValue); + /// Parameter `value` should be the value computed from previous devices. + /// And it should greater than zero. + /// `device_kind` is the kind of the device. + pub fn compute(&self, value: f64, device_kind: DeviceKind) -> Result { + // Check the range of provided value for computing + if !(value > 0f64) { + return Err(SubCircuitError::BadPreviousValue(value)); } // We perform series connect for: series resistor, series inductor and parallel capacitor. // We perform parallel connect for: parallel resistor, parallel inductor and series capacitor. - let joint_kind = if device_kind == DeviceKind::Capacitor { - self.joint_kind.flip() - } else { - self.joint_kind + let joint_kind = match device_kind { + DeviceKind::Capacitor => self.joint_kind.flip(), + _ => self.joint_kind, }; - Ok(match joint_kind { + let rv = match joint_kind { JointKind::Series => self.device_value + value, JointKind::Parallel => (self.device_value * value) / (self.device_value + value), - }) + }; + if rv.is_finite() { + Ok(rv) + } else { + Err(SubCircuitError::BadArithmetic) + } } /// Get the device value. @@ -153,7 +112,7 @@ impl SubCircuit { } /// The scale of devices in the circuit. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy)] pub enum CircuitDeviceScale { /// One device. One, @@ -165,10 +124,7 @@ pub enum CircuitDeviceScale { impl CircuitDeviceScale { /// Convert circuit device scale to device count. - /// - /// # Returns - /// - /// The device count. + /// The return value only can be 1, 2, and 3. pub fn to_device_count(self) -> usize { match self { CircuitDeviceScale::One => 1, @@ -178,6 +134,19 @@ impl CircuitDeviceScale { } } +/// Error occurs when manipulating [Circuit]. +#[derive(Debug, TeError)] +pub enum CircuitError { + #[error("given circuit device value {0} should greater than zero")] + BadDeviceValue(f64), + #[error("third device cannot exist without second device when building circuit")] + BlankSecondSubCircuit, + #[error("{0}")] + SubCircuit(#[from] SubCircuitError), + #[error("the joint or device with given index is not presented in circuit")] + NoSuchDevice, +} + /// The circuit composed of multiple joints. #[derive(Clone, Debug)] pub struct Circuit { @@ -190,27 +159,26 @@ pub struct Circuit { } impl Circuit { - /// Initialize the circuit. - /// - /// # Arguments + /// Initialize the circuit with subcircuit. /// /// * `first_device_value` - The value of the first device. /// * `second_device_subckt` - The second device and its joint property. /// * `third_device_subckt` - The third device and its joint property. - /// - /// # Errors - /// - /// Returns [`LcrConnError::ThirdDeviceWithoutSecond`] if a third device is provided - /// without a second device. - pub fn new( + fn new( first_device_value: f64, second_device_subckt: Option, third_device_subckt: Option, - ) -> Result { + ) -> Result { + // Check the value of first device + if !(first_device_value > 0f64) { + return Err(CircuitError::BadDeviceValue(first_device_value)); + } + // Check impossible form if second_device_subckt.is_none() && third_device_subckt.is_some() { - return Err(LcrConnError::ThirdDeviceWithoutSecond); + return Err(CircuitError::BlankSecondSubCircuit); } + // Everything is okey Ok(Self { first_device_value, second_device_subckt, @@ -219,12 +187,8 @@ impl Circuit { } /// Create a circuit from a single device. - pub fn from_one_device(device1_value: f64) -> Self { - Self { - first_device_value: device1_value, - second_device_subckt: None, - third_device_subckt: None, - } + pub fn from_one_device(device1_value: f64) -> Result { + Self::new(device1_value, None, None) } /// Create a circuit from two devices. @@ -232,12 +196,12 @@ impl Circuit { device1_value: f64, device2_value: f64, device2_joint: JointKind, - ) -> Self { - Self { - first_device_value: device1_value, - second_device_subckt: Some(SubCircuit::new(device2_value, device2_joint)), - third_device_subckt: None, - } + ) -> Result { + Self::new( + device1_value, + Some(SubCircuit::new(device2_value, device2_joint)?), + None, + ) } /// Create a circuit from three devices. @@ -247,41 +211,28 @@ impl Circuit { device2_joint: JointKind, device3_value: f64, device3_joint: JointKind, - ) -> Self { - Self { - first_device_value: device1_value, - second_device_subckt: Some(SubCircuit::new(device2_value, device2_joint)), - third_device_subckt: Some(SubCircuit::new(device3_value, device3_joint)), - } + ) -> Result { + Self::new( + device1_value, + Some(SubCircuit::new(device2_value, device2_joint)?), + Some(SubCircuit::new(device3_value, device3_joint)?), + ) } - /// Compute the circuit value. - /// - /// # Arguments - /// - /// * `device_kind` - The kind of the device. - /// - /// # Returns - /// - /// The circuit value. - /// - /// # Errors - /// - /// Returns [`LcrConnError::InvalidDeviceValue`] if any device value is not greater than 0. - pub fn compute(&self, device_kind: DeviceKind) -> Result { - if self.first_device_value <= 0.0 { - return Err(LcrConnError::InvalidDeviceValue); + /// Compute the circuit value with given value and device kind + pub fn compute(&self, device_kind: DeviceKind) -> Result { + let mut value = self.first_device_value; + + match &self.second_device_subckt { + Some(subckt) => value = subckt.compute(value, device_kind)?, + None => return Ok(value), } - let mut value = self.first_device_value; - if let Some(subckt) = &self.second_device_subckt { - value = subckt.compute(value, device_kind)?; - } else { - return Ok(value); - } - if let Some(subckt) = &self.third_device_subckt { - value = subckt.compute(value, device_kind)?; + match &self.third_device_subckt { + Some(subckt) => value = subckt.compute(value, device_kind)?, + None => return Ok(value), } + Ok(value) } @@ -306,82 +257,76 @@ impl Circuit { } /// Get the joint kind of the second device. - /// - /// # Errors - /// - /// Returns [`LcrConnError::NoSecondDevice`] if there is no second device. - pub fn second_device_joint(&self) -> Result { + pub fn second_device_joint(&self) -> Result { self.second_device_subckt + .as_ref() .map(|s| s.joint_kind()) - .ok_or(LcrConnError::NoSecondDevice) + .ok_or(CircuitError::NoSuchDevice) } /// Get the value of the second device. - /// - /// # Errors - /// - /// Returns [`LcrConnError::NoSecondDevice`] if there is no second device. - pub fn second_device_value(&self) -> Result { + pub fn second_device_value(&self) -> Result { self.second_device_subckt + .as_ref() .map(|s| s.device_value()) - .ok_or(LcrConnError::NoSecondDevice) + .ok_or(CircuitError::NoSuchDevice) } /// Get the joint kind of the third device. - /// - /// # Errors - /// - /// Returns [`LcrConnError::NoThirdDevice`] if there is no third device. - pub fn third_device_joint(&self) -> Result { + pub fn third_device_joint(&self) -> Result { self.third_device_subckt + .as_ref() .map(|s| s.joint_kind()) - .ok_or(LcrConnError::NoThirdDevice) + .ok_or(CircuitError::NoSuchDevice) } /// Get the value of the third device. - /// - /// # Errors - /// - /// Returns [`LcrConnError::NoThirdDevice`] if there is no third device. - pub fn third_device_value(&self) -> Result { + pub fn third_device_value(&self) -> Result { self.third_device_subckt + .as_ref() .map(|s| s.device_value()) - .ok_or(LcrConnError::NoThirdDevice) + .ok_or(CircuitError::NoSuchDevice) } } +/// Error occurs when manipulating [CircuitCalculator]. +#[derive(Debug, TeError)] +pub enum CircuitCalculatorError { + #[error("given target value {0} should be greater than zero")] + BadTargetValue(f64), + #[error("{0}")] + Circuit(#[from] CircuitError), + #[error("bad float point arithmetic")] + BadArithmetic, + #[error("provided value {0} reducing computation steps is invalid")] + BadReuseValue(f64), +} + /// The helper for circuit value computation. -#[derive(Clone, Debug)] -pub struct CircuitValueTrait { +#[derive(Debug, Clone)] +pub struct CircuitCalculator { /// The kind of the device. device_kind: DeviceKind, /// The target value. target_value: f64, } -impl CircuitValueTrait { - pub fn new(device_kind: DeviceKind, target_value: f64) -> Self { - Self { - device_kind, - target_value, +impl CircuitCalculator { + /// Initialize this calculator with given device kind and target value. + pub fn new(device_kind: DeviceKind, target_value: f64) -> Result { + if target_value > 0f64 { + Ok(Self { + device_kind, + target_value, + }) + } else { + Err(CircuitCalculatorError::BadTargetValue(target_value)) } } /// The value of this circuit. - /// - /// # Arguments - /// - /// * `circuit` - The circuit for computation. - /// - /// # Returns - /// - /// The value. - /// - /// # Errors - /// - /// See [`Circuit::compute`]. - pub fn value(&self, circuit: &Circuit) -> Result { - circuit.compute(self.device_kind) + pub fn value(&self, circuit: &Circuit) -> Result { + Ok(circuit.compute(self.device_kind)?) } /// The signed difference between the target value and the value of this circuit. @@ -389,56 +334,64 @@ impl CircuitValueTrait { /// Positive value indicates that the value of this circuit is greater than the target value. /// Negative value indicates that the value of this circuit is less than the target value. /// - /// # Arguments - /// /// * `circuit` - The circuit for computation. /// * `value` - The value of the circuit computed by the [`value`](Self::value) method /// for reducing computation steps, or `None` if you request this method to compute the value. - /// - /// # Returns - /// - /// The signed difference. - /// - /// # Errors - /// - /// See [`Circuit::compute`]. - pub fn difference(&self, circuit: &Circuit, value: Option) -> Result { + pub fn difference( + &self, + circuit: &Circuit, + value: Option, + ) -> Result { let value = match value { - Some(v) => v, + Some(v) => { + if v.is_finite() { + v + } else { + return Err(CircuitCalculatorError::BadReuseValue(v)); + } + } None => self.value(circuit)?, }; - Ok(value - self.target_value) + + let rv = value - self.target_value; + if rv.is_finite() { + Ok(rv) + } else { + Err(CircuitCalculatorError::BadArithmetic) + } } /// The unsigned difference between the target value and the value of this circuit. /// - /// # Arguments - /// /// * `circuit` - The circuit for computation. /// * `value` - The value of the circuit computed by the [`value`](Self::value) method /// for reducing computation steps, or `None` if you request this method to compute the value. /// * `difference` - The difference of the circuit computed by the /// [`difference`](Self::difference) method for reducing computation steps, /// or `None` if you request this method to compute the difference. - /// - /// # Returns - /// - /// The unsigned difference. - /// - /// # Errors - /// - /// See [`Circuit::compute`]. pub fn unsigned_difference( &self, circuit: &Circuit, value: Option, difference: Option, - ) -> Result { + ) -> Result { let diff = match difference { - Some(d) => d, + Some(d) => { + if d.is_finite() { + d + } else { + return Err(CircuitCalculatorError::BadReuseValue(d)); + } + } None => self.difference(circuit, value)?, }; - Ok(diff.abs()) + + let rv = diff.abs(); + if rv.is_finite() { + Ok(rv) + } else { + Err(CircuitCalculatorError::BadArithmetic) + } } /// The signed relative difference between the target value and the value of this circuit. @@ -446,39 +399,39 @@ impl CircuitValueTrait { /// Positive value indicates that the value of this circuit is greater than the target value. /// Negative value indicates that the value of this circuit is less than the target value. /// - /// # Arguments - /// /// * `circuit` - The circuit for computation. /// * `value` - The value of the circuit computed by the [`value`](Self::value) method /// for reducing computation steps, or `None` if you request this method to compute the value. /// * `difference` - The difference of the circuit computed by the /// [`difference`](Self::difference) method for reducing computation steps, /// or `None` if you request this method to compute the difference. - /// - /// # Returns - /// - /// The signed relative difference. - /// - /// # Errors - /// - /// See [`Circuit::compute`]. pub fn relative_difference( &self, circuit: &Circuit, value: Option, difference: Option, - ) -> Result { + ) -> Result { let diff = match difference { - Some(d) => d, + Some(d) => { + if d.is_finite() { + d + } else { + return Err(CircuitCalculatorError::BadReuseValue(d)); + } + } None => self.difference(circuit, value)?, }; - Ok(diff / self.target_value) + + let rv = diff / self.target_value; + if rv.is_finite() { + Ok(rv) + } else { + Err(CircuitCalculatorError::BadArithmetic) + } } /// The unsigned relative difference between the target value and the value of this circuit. /// - /// # Arguments - /// /// * `circuit` - The circuit for computation. /// * `value` - The value of the circuit computed by the [`value`](Self::value) method /// for reducing computation steps, or `None` if you request this method to compute the value. @@ -489,24 +442,29 @@ impl CircuitValueTrait { /// [`relative_difference`](Self::relative_difference) method for reducing computation steps, /// or `None` if you request this method to compute the relative difference. /// - /// # Returns - /// - /// The unsigned relative difference. - /// - /// # Errors - /// - /// See [`Circuit::compute`]. pub fn unsigned_relative_difference( &self, circuit: &Circuit, value: Option, difference: Option, relative_difference: Option, - ) -> Result { + ) -> Result { let rel_diff = match relative_difference { - Some(rd) => rd, + Some(rd) => { + if rd.is_finite() { + rd + } else { + return Err(CircuitCalculatorError::BadReuseValue(rd)); + } + } None => self.relative_difference(circuit, value, difference)?, }; - Ok(rel_diff.abs()) + + let rv = rel_diff.abs(); + if rv.is_finite() { + Ok(rv) + } else { + Err(CircuitCalculatorError::BadArithmetic) + } } } diff --git a/kernel/lcrconn/src/lib.rs b/kernel/lcrconn/src/lib.rs index cddbfb5..0c1f0e4 100644 --- a/kernel/lcrconn/src/lib.rs +++ b/kernel/lcrconn/src/lib.rs @@ -4,7 +4,7 @@ pub mod query; pub mod resolver; pub use common::{ - Circuit, CircuitDeviceScale, CircuitValueTrait, DeviceKind, JointKind, LcrConnError, SubCircuit, + Circuit, CircuitDeviceScale, CircuitCalculator, DeviceKind, JointKind, LcrConnError, SubCircuit, }; pub use dataset::{ from_human_readable_value, get_human_readable_value_scale, to_human_readable_value, Dataset, diff --git a/kernel/lcrconn/src/query.rs b/kernel/lcrconn/src/query.rs index 20d3acb..968a184 100644 --- a/kernel/lcrconn/src/query.rs +++ b/kernel/lcrconn/src/query.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; use std::ops::Index; -use crate::common::{Circuit, CircuitValueTrait, DeviceKind, LcrConnError}; +use crate::common::{Circuit, CircuitCalculator, DeviceKind, LcrConnError}; /// The priority of the result. #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -96,7 +96,7 @@ impl ResponseItem { /// # Errors /// /// See [`CircuitValueTrait::value`]. - pub fn new(circuit: Circuit, cv_trait: &CircuitValueTrait) -> Result { + pub fn new(circuit: Circuit, cv_trait: &CircuitCalculator) -> Result { let value = cv_trait.value(&circuit)?; let difference = cv_trait.difference(&circuit, Some(value))?; let unsigned_difference = cv_trait.unsigned_difference(&circuit, None, Some(difference))?; @@ -183,7 +183,7 @@ impl Response { request: &Request, candidates: impl IntoIterator, ) -> Result { - let cv_trait = CircuitValueTrait::new(request.device_kind, request.target_value); + let cv_trait = CircuitCalculator::new(request.device_kind, request.target_value); let mut items: Vec = candidates .into_iter() diff --git a/kernel/lcrconn/src/resolver/bfs.rs b/kernel/lcrconn/src/resolver/bfs.rs index dbb368a..b9771b5 100644 --- a/kernel/lcrconn/src/resolver/bfs.rs +++ b/kernel/lcrconn/src/resolver/bfs.rs @@ -3,7 +3,7 @@ use std::collections::BinaryHeap; use std::iter::FusedIterator; use super::Resolver; -use crate::common::{Circuit, CircuitValueTrait, DeviceKind, JointKind, LcrConnError}; +use crate::common::{Circuit, CircuitCalculator, DeviceKind, JointKind, LcrConnError}; use crate::dataset::{Dataset, DatasetCollection, DatasetItem}; use crate::query::{Request, Response}; @@ -263,7 +263,7 @@ impl BfsItem { /// # Errors /// /// See [`CircuitValueTrait::value`]. - pub fn new(circuit: Circuit, cv_trait: &CircuitValueTrait) -> Result { + pub fn new(circuit: Circuit, cv_trait: &CircuitCalculator) -> Result { let value = cv_trait.value(&circuit)?; let unsigned_difference = cv_trait.unsigned_difference(&circuit, Some(value))?; Ok(Self { @@ -454,7 +454,7 @@ impl Resolver for BfsResolver { // Iterate circuit item one by one let mut bucket = ResultBucket::new(request.count_limit); - let cv_trait = CircuitValueTrait::new(request.device_kind, request.target_value); + let cv_trait = CircuitCalculator::new(request.device_kind, request.target_value); let circuits = Self::iter_one_device_circuit(dataset) .chain(Self::iter_two_devices_circuit(dataset)) diff --git a/kernel/lcrconn/src/resolver/lut.rs b/kernel/lcrconn/src/resolver/lut.rs index 93a2bab..39217a8 100644 --- a/kernel/lcrconn/src/resolver/lut.rs +++ b/kernel/lcrconn/src/resolver/lut.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use super::bfs::BfsResolver; use super::Resolver; -use crate::common::{Circuit, CircuitValueTrait, DeviceKind, LcrConnError}; +use crate::common::{Circuit, CircuitCalculator, DeviceKind, LcrConnError}; use crate::dataset::{Dataset, DatasetCollection}; use crate::query::{Request, Response}; @@ -104,7 +104,7 @@ impl Resolver for LutResolver { let mut right = idx as isize; let lut_len = lut.len() as isize; - let cv_trait = CircuitValueTrait::new(request.device_kind, target); + let cv_trait = CircuitCalculator::new(request.device_kind, target); while left >= 0 || right < lut_len { if bucket.len() >= count_limit {