fix: fix dataset build issue
This commit is contained in:
41
kernel/Cargo.lock
generated
41
kernel/Cargo.lock
generated
@@ -52,6 +52,12 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.6.1"
|
version = "4.6.1"
|
||||||
@@ -98,6 +104,12 @@ version = "1.0.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -110,10 +122,21 @@ version = "1.70.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lcrconn"
|
name = "lcrconn"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
"ordered-float",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -128,12 +151,30 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell_polyfill"
|
name = "once_cell_polyfill"
|
||||||
version = "1.70.2"
|
version = "1.70.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-float"
|
||||||
|
version = "5.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.106"
|
version = "1.0.106"
|
||||||
|
|||||||
@@ -5,5 +5,7 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
|
ordered-float = "=5.3.0"
|
||||||
|
itertools = "0.15.0"
|
||||||
strum = "=0.28.0"
|
strum = "=0.28.0"
|
||||||
strum_macros = "=0.28.0"
|
strum_macros = "=0.28.0"
|
||||||
|
|||||||
@@ -1,35 +1,51 @@
|
|||||||
use thiserror::Error as TeError;
|
use crate::common::{
|
||||||
|
DeviceValueError, FloatingPointError, sanitize_device_value, sanitize_floating_point,
|
||||||
|
};
|
||||||
|
use ordered_float::OrderedFloat;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader, BufWriter, Error as IoError, Write};
|
||||||
|
use std::num::ParseFloatError;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use thiserror::Error as TeError;
|
||||||
|
|
||||||
/// Error occurs when building dataset.
|
/// Error occurs when building dataset.
|
||||||
#[derive(Debug, TeError)]
|
#[derive(Debug, TeError)]
|
||||||
pub enum DatasetError {
|
pub enum DatasetError {
|
||||||
|
#[error("invalid device value {0} in dataset item")]
|
||||||
|
BadDeviceValue(#[from] DeviceValueError),
|
||||||
|
#[error("unexpected empty string in dataset item")]
|
||||||
|
BlankDeviceValue,
|
||||||
|
#[error("bad string form of device value: {0}")]
|
||||||
|
ParseHumanReadableValue(#[from] ParseHumanReadableValueError),
|
||||||
|
#[error("duplicate item {0} in standard value list")]
|
||||||
|
DupDatasetItem(String),
|
||||||
|
#[error("unexpected empty standard value list")]
|
||||||
|
EmptyDataset,
|
||||||
|
#[error("fail to open dataset file: {0}")]
|
||||||
|
OpenDatasetFile(IoError),
|
||||||
|
#[error("fail to read dataset file: {0}")]
|
||||||
|
ReadDatasetFile(IoError),
|
||||||
|
#[error("fail to write dataset file: {0}")]
|
||||||
|
WriteDatasetFile(IoError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An item in the dataset.
|
/// An item in the dataset.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DatasetItem {
|
struct DatasetItem {
|
||||||
/// The actual value of this item.
|
/// The actual value of this item.
|
||||||
pub value: f64,
|
value: f64,
|
||||||
/// The string form of this value given from original input for re-saving.
|
/// The string form of this value given from original input for re-saving.
|
||||||
pub str_value: String,
|
str_value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DatasetItem {
|
impl DatasetItem {
|
||||||
/// Create a new dataset item with validation.
|
/// Create a new dataset item with validation.
|
||||||
///
|
fn new(value: f64, str_value: String) -> Result<Self, DatasetError> {
|
||||||
/// # Errors
|
// Check arguments
|
||||||
///
|
let value = sanitize_device_value(value)?;
|
||||||
/// Returns [`DatasetError::InvalidDatasetValue`] if the value is not greater than 0.
|
|
||||||
/// Returns [`DatasetError::EmptyDatasetItem`] if the string value is empty.
|
|
||||||
pub fn new(value: f64, str_value: String) -> Result<Self, DatasetError> {
|
|
||||||
if value <= 0.0 {
|
|
||||||
return Err(DatasetError::InvalidDatasetValue(value));
|
|
||||||
}
|
|
||||||
if str_value.is_empty() {
|
if str_value.is_empty() {
|
||||||
return Err(DatasetError::EmptyDatasetItem);
|
return Err(DatasetError::BlankDeviceValue);
|
||||||
}
|
}
|
||||||
Ok(Self { value, str_value })
|
Ok(Self { value, str_value })
|
||||||
}
|
}
|
||||||
@@ -47,29 +63,21 @@ pub struct Dataset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Dataset {
|
impl Dataset {
|
||||||
/// Create a dataset from an iterable of stringified values.
|
/// Internal used generic dataset creation function.
|
||||||
///
|
fn new<I>(str_values: I) -> Result<Self, DatasetError>
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns [`DatasetError::DuplicateDatasetItem`] if duplicate values are found.
|
|
||||||
/// Returns [`DatasetError::EmptyDataset`] if the iterable produces no items.
|
|
||||||
/// Returns [`DatasetError::InvalidHumanReadableValue`] if a value cannot be parsed.
|
|
||||||
pub fn from_iterable<I, S>(str_values: I) -> Result<Self, DatasetError>
|
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = S>,
|
I: IntoIterator<Item = String>,
|
||||||
S: Into<String>,
|
|
||||||
{
|
{
|
||||||
// Check string form value one by one
|
// Check string form value one by one
|
||||||
let mut items: Vec<DatasetItem> = Vec::new();
|
let mut items: Vec<DatasetItem> = Vec::new();
|
||||||
let mut seen: HashSet<f64> = HashSet::new();
|
let mut seen: HashSet<OrderedFloat<f64>> = HashSet::new();
|
||||||
|
|
||||||
for str_value_raw in str_values {
|
for str_value in str_values {
|
||||||
let str_value = str_value_raw.into();
|
|
||||||
// Try parsing value
|
// Try parsing value
|
||||||
let value = from_human_readable_value(&str_value)?;
|
let value = from_human_readable_value(&str_value)?;
|
||||||
// Check and update set
|
// Check and update set
|
||||||
if !seen.insert(value) {
|
if !seen.insert(OrderedFloat(value)) {
|
||||||
return Err(DatasetError::DuplicateDatasetItem(str_value));
|
return Err(DatasetError::DupDatasetItem(str_value.to_string()));
|
||||||
}
|
}
|
||||||
// Add into result
|
// Add into result
|
||||||
items.push(DatasetItem::new(value, str_value)?);
|
items.push(DatasetItem::new(value, str_value)?);
|
||||||
@@ -84,97 +92,104 @@ impl Dataset {
|
|||||||
Ok(Self { items })
|
Ok(Self { items })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a dataset from an iterable of string values.
|
||||||
|
pub fn from_iterator<I, S>(str_values: I) -> Result<Self, DatasetError>
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = S>,
|
||||||
|
S: Into<String>,
|
||||||
|
{
|
||||||
|
Self::new(str_values.into_iter().map(|i| i.into()))
|
||||||
|
}
|
||||||
|
|
||||||
/// Load a dataset from a block of text.
|
/// Load a dataset from a block of text.
|
||||||
///
|
///
|
||||||
/// Each non-empty line (after trimming whitespace) is treated as a value.
|
/// Each non-empty line (after trimming whitespace) is treated as a value.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// See [`Dataset::from_iterable`].
|
|
||||||
pub fn from_text(text: &str) -> Result<Self, DatasetError> {
|
pub fn from_text(text: &str) -> Result<Self, DatasetError> {
|
||||||
let lines: Vec<String> = text
|
let lines = text
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| line.trim().to_string())
|
.map(|line| line.trim().to_string())
|
||||||
.filter(|line| !line.is_empty())
|
.filter(|line| !line.is_empty());
|
||||||
.collect();
|
Self::from_iterator(lines)
|
||||||
Self::from_iterable(lines)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a dataset from a file.
|
/// Load a dataset from a file.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// Each non-empty line (after trimming whitespace) is treated as a value.
|
||||||
///
|
pub fn from_file<P>(path: P) -> Result<Self, DatasetError>
|
||||||
/// Returns [`DatasetError::Io`] if the file cannot be read.
|
where
|
||||||
/// See [`Dataset::from_iterable`] for other errors.
|
P: AsRef<Path>,
|
||||||
pub fn from_file(path: impl AsRef<Path>) -> Result<Self, DatasetError> {
|
{
|
||||||
let text = std::fs::read_to_string(path)?;
|
let file = File::open(path).map_err(|err| DatasetError::OpenDatasetFile(err))?;
|
||||||
Self::from_text(&text)
|
let reader = BufReader::new(file);
|
||||||
|
let lines = reader
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.map(|line| line.trim().to_string()))
|
||||||
|
.filter(|line| !matches!(line, Ok(line) if line.is_empty()))
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.map_err(|err| DatasetError::ReadDatasetFile(err))?;
|
||||||
|
Self::from_iterator(lines.into_iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The preset dataset for resistors.
|
/// The preset dataset for resistors.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// See [`Dataset::from_iterable`].
|
|
||||||
pub fn resistor_preset() -> Result<Self, DatasetError> {
|
pub fn resistor_preset() -> Result<Self, DatasetError> {
|
||||||
Self::from_iterable([
|
Self::from_iterator([
|
||||||
"100", "220", "270", "390", "470", "680", "1k", "1.2k", "1.5k", "2.2k", "3.3k",
|
"100", "220", "270", "390", "470", "680", "1k", "1.2k", "1.5k", "2.2k", "3.3k", "4.7k",
|
||||||
"4.7k", "6.8k", "10k", "47k", "100k", "1M",
|
"6.8k", "10k", "47k", "100k", "1M",
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The preset dataset for capacitors.
|
/// The preset dataset for capacitors.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// See [`Dataset::from_iterable`].
|
|
||||||
pub fn capacitor_preset() -> Result<Self, DatasetError> {
|
pub fn capacitor_preset() -> Result<Self, DatasetError> {
|
||||||
Self::from_iterable([
|
Self::from_iterator([
|
||||||
"10p", "22p", "33p", "47p", "68p", "100p", "150p", "220p", "330p", "470p", "560p",
|
"10p", "22p", "33p", "47p", "68p", "100p", "150p", "220p", "330p", "470p", "560p",
|
||||||
"1u", "2.2u", "3.3u", "4.7u", "10u", "22u", "47u", "100u", "220u", "470u",
|
"1u", "2.2u", "3.3u", "4.7u", "10u", "22u", "47u", "100u", "220u", "470u",
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The preset dataset for inductors.
|
/// The preset dataset for inductors.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// See [`Dataset::from_iterable`].
|
|
||||||
pub fn inductor_preset() -> Result<Self, DatasetError> {
|
pub fn inductor_preset() -> Result<Self, DatasetError> {
|
||||||
Self::from_iterable([
|
Self::from_iterator([
|
||||||
"0.1u", "0.15u", "0.47u", "0.68u", "1u", "1.5u", "2.2u", "3.3u", "4.7u", "6.8u",
|
"0.1u", "0.15u", "0.47u", "0.68u", "1u", "1.5u", "2.2u", "3.3u", "4.7u", "6.8u",
|
||||||
"8.2u", "10u", "15u", "22u", "33u", "47u", "68u", "100u",
|
"8.2u", "10u", "15u", "22u", "33u", "47u", "68u", "100u",
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the string form of all values joined by newlines.
|
fn save(&self) -> impl Iterator<Item = &str> {
|
||||||
pub fn save_text(&self) -> String {
|
self.items.iter().map(|i| i.str_value.as_str())
|
||||||
self.items
|
|
||||||
.iter()
|
|
||||||
.map(|i| i.str_value.as_str())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save all values to a file.
|
/// Get the string form of all values one by one for saving
|
||||||
///
|
pub fn save_iterator(&self) -> impl Iterator<Item = &str> {
|
||||||
/// # Errors
|
self.save()
|
||||||
///
|
}
|
||||||
/// Returns [`DatasetError::Io`] if the file cannot be written.
|
|
||||||
pub fn save_file(&self, path: impl AsRef<Path>) -> Result<(), DatasetError> {
|
/// Get the string form of all values joined by newlines for saving./
|
||||||
std::fs::write(path, self.save_text())?;
|
pub fn save_text(&self) -> String {
|
||||||
|
itertools::join(self.save_iterator(), "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save all values joined by newlines to a file.
|
||||||
|
pub fn save_file<P>(&self, path: P) -> Result<(), DatasetError>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let file = File::open(path).map_err(|err| DatasetError::OpenDatasetFile(err))?;
|
||||||
|
let mut writer = BufWriter::new(file);
|
||||||
|
for line in self.save_iterator() {
|
||||||
|
writer
|
||||||
|
.write_all(line.as_bytes())
|
||||||
|
.map_err(|err| DatasetError::WriteDatasetFile(err))?;
|
||||||
|
writer
|
||||||
|
.write_all("\n".as_bytes())
|
||||||
|
.map_err(|err| DatasetError::WriteDatasetFile(err))?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the available standard values as an iterator of `f64`.
|
/// Get the available standard values as an iterator of `f64`.
|
||||||
pub fn values(&self) -> impl Iterator<Item = f64> + '_ {
|
pub fn values(&self) -> impl Iterator<Item = f64> {
|
||||||
self.items.iter().map(|i| i.value)
|
self.items.iter().map(|i| i.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying dataset items as a slice.
|
|
||||||
pub fn items(&self) -> &[DatasetItem] {
|
|
||||||
&self.items
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The collection holding all standard values for resistor, capacitor and inductor respectively.
|
/// The collection holding all standard values for resistor, capacitor and inductor respectively.
|
||||||
@@ -188,6 +203,7 @@ pub struct DatasetCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DatasetCollection {
|
impl DatasetCollection {
|
||||||
|
/// Create dataset collection with 3 datasets for resistor, capacitor and inductor respectively.
|
||||||
pub fn new(resistor: Dataset, capacitor: Dataset, inductor: Dataset) -> Self {
|
pub fn new(resistor: Dataset, capacitor: Dataset, inductor: Dataset) -> Self {
|
||||||
Self {
|
Self {
|
||||||
resistor,
|
resistor,
|
||||||
@@ -198,15 +214,9 @@ impl DatasetCollection {
|
|||||||
|
|
||||||
/// Load the standard values for resistor, capacitor and inductor respectively from iterables.
|
/// Load the standard values for resistor, capacitor and inductor respectively from iterables.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `resistor` - The iterable to load available standard values for resistor.
|
/// * `resistor` - The iterable to load available standard values for resistor.
|
||||||
/// * `capacitor` - The iterable to load available standard values for capacitor.
|
/// * `capacitor` - The iterable to load available standard values for capacitor.
|
||||||
/// * `inductor` - The iterable to load available standard values for inductor.
|
/// * `inductor` - The iterable to load available standard values for inductor.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// See [`Dataset::from_iterable`].
|
|
||||||
pub fn from_iterable<I1, S1, I2, S2, I3, S3>(
|
pub fn from_iterable<I1, S1, I2, S2, I3, S3>(
|
||||||
resistor: I1,
|
resistor: I1,
|
||||||
capacitor: I2,
|
capacitor: I2,
|
||||||
@@ -221,24 +231,22 @@ impl DatasetCollection {
|
|||||||
S3: Into<String>,
|
S3: Into<String>,
|
||||||
{
|
{
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
resistor: Dataset::from_iterable(resistor)?,
|
resistor: Dataset::from_iterator(resistor)?,
|
||||||
capacitor: Dataset::from_iterable(capacitor)?,
|
capacitor: Dataset::from_iterator(capacitor)?,
|
||||||
inductor: Dataset::from_iterable(inductor)?,
|
inductor: Dataset::from_iterator(inductor)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the standard values from strings.
|
/// Load the standard values from strings.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `resistor` - The string to load available standard values for resistor.
|
/// * `resistor` - The string to load available standard values for resistor.
|
||||||
/// * `capacitor` - The string to load available standard values for capacitor.
|
/// * `capacitor` - The string to load available standard values for capacitor.
|
||||||
/// * `inductor` - The string to load available standard values for inductor.
|
/// * `inductor` - The string to load available standard values for inductor.
|
||||||
///
|
pub fn from_text(
|
||||||
/// # Errors
|
resistor: &str,
|
||||||
///
|
capacitor: &str,
|
||||||
/// See [`Dataset::from_text`].
|
inductor: &str,
|
||||||
pub fn from_text(resistor: &str, capacitor: &str, inductor: &str) -> Result<Self, DatasetError> {
|
) -> Result<Self, DatasetError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
resistor: Dataset::from_text(resistor)?,
|
resistor: Dataset::from_text(resistor)?,
|
||||||
capacitor: Dataset::from_text(capacitor)?,
|
capacitor: Dataset::from_text(capacitor)?,
|
||||||
@@ -248,20 +256,19 @@ impl DatasetCollection {
|
|||||||
|
|
||||||
/// Load the standard values from files.
|
/// Load the standard values from files.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `resistor` - The file to load available standard values for resistor.
|
/// * `resistor` - The file to load available standard values for resistor.
|
||||||
/// * `capacitor` - The file to load available standard values for capacitor.
|
/// * `capacitor` - The file to load available standard values for capacitor.
|
||||||
/// * `inductor` - The file to load available standard values for inductor.
|
/// * `inductor` - The file to load available standard values for inductor.
|
||||||
///
|
pub fn from_file<P1, P2, P3>(
|
||||||
/// # Errors
|
resistor: P1,
|
||||||
///
|
capacitor: P2,
|
||||||
/// See [`Dataset::from_file`].
|
inductor: P3,
|
||||||
pub fn from_file(
|
) -> Result<Self, DatasetError>
|
||||||
resistor: impl AsRef<Path>,
|
where
|
||||||
capacitor: impl AsRef<Path>,
|
P1: AsRef<Path>,
|
||||||
inductor: impl AsRef<Path>,
|
P2: AsRef<Path>,
|
||||||
) -> Result<Self, DatasetError> {
|
P3: AsRef<Path>,
|
||||||
|
{
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
resistor: Dataset::from_file(resistor)?,
|
resistor: Dataset::from_file(resistor)?,
|
||||||
capacitor: Dataset::from_file(capacitor)?,
|
capacitor: Dataset::from_file(capacitor)?,
|
||||||
@@ -270,10 +277,6 @@ impl DatasetCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The preset dataset collection for all devices.
|
/// The preset dataset collection for all devices.
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// See [`Dataset::from_iterable`].
|
|
||||||
pub fn devices_preset() -> Result<Self, DatasetError> {
|
pub fn devices_preset() -> Result<Self, DatasetError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
resistor: Dataset::resistor_preset()?,
|
resistor: Dataset::resistor_preset()?,
|
||||||
@@ -282,11 +285,22 @@ impl DatasetCollection {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the string form of all values.
|
/// Get the iterators for saving resistor, capacitor and inductor dataset respectively.
|
||||||
///
|
pub fn save_iterator(
|
||||||
/// # Returns
|
&self,
|
||||||
///
|
) -> (
|
||||||
/// A tuple of strings for resistor, capacitor and inductor respectively.
|
impl Iterator<Item = &str>,
|
||||||
|
impl Iterator<Item = &str>,
|
||||||
|
impl Iterator<Item = &str>,
|
||||||
|
) {
|
||||||
|
(
|
||||||
|
self.resistor.save_iterator(),
|
||||||
|
self.capacitor.save_iterator(),
|
||||||
|
self.inductor.save_iterator(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the string form of all values for saving resistor, capacitor and inductor dataset respectively.
|
||||||
pub fn save_text(&self) -> (String, String, String) {
|
pub fn save_text(&self) -> (String, String, String) {
|
||||||
(
|
(
|
||||||
self.resistor.save_text(),
|
self.resistor.save_text(),
|
||||||
@@ -297,21 +311,20 @@ impl DatasetCollection {
|
|||||||
|
|
||||||
/// Save all values to files.
|
/// Save all values to files.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `resistor` - The file to save available standard values for resistor.
|
/// * `resistor` - The file to save available standard values for resistor.
|
||||||
/// * `capacitor` - The file to save available standard values for capacitor.
|
/// * `capacitor` - The file to save available standard values for capacitor.
|
||||||
/// * `inductor` - The file to save available standard values for inductor.
|
/// * `inductor` - The file to save available standard values for inductor.
|
||||||
///
|
pub fn save_file<P1, P2, P3>(
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns [`DatasetError::Io`] if any file cannot be written.
|
|
||||||
pub fn save_file(
|
|
||||||
&self,
|
&self,
|
||||||
resistor: impl AsRef<Path>,
|
resistor: P1,
|
||||||
capacitor: impl AsRef<Path>,
|
capacitor: P2,
|
||||||
inductor: impl AsRef<Path>,
|
inductor: P3,
|
||||||
) -> Result<(), DatasetError> {
|
) -> Result<(), DatasetError>
|
||||||
|
where
|
||||||
|
P1: AsRef<Path>,
|
||||||
|
P2: AsRef<Path>,
|
||||||
|
P3: AsRef<Path>,
|
||||||
|
{
|
||||||
self.resistor.save_file(resistor)?;
|
self.resistor.save_file(resistor)?;
|
||||||
self.capacitor.save_file(capacitor)?;
|
self.capacitor.save_file(capacitor)?;
|
||||||
self.inductor.save_file(inductor)?;
|
self.inductor.save_file(inductor)?;
|
||||||
@@ -319,39 +332,34 @@ impl DatasetCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the dataset for resistor.
|
/// Get the dataset for resistor.
|
||||||
pub fn resistor(&self) -> &Dataset {
|
pub fn resistor_dataset(&self) -> &Dataset {
|
||||||
&self.resistor
|
&self.resistor
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the dataset for capacitor.
|
/// Get the dataset for capacitor.
|
||||||
pub fn capacitor(&self) -> &Dataset {
|
pub fn capacitor_dataset(&self) -> &Dataset {
|
||||||
&self.capacitor
|
&self.capacitor
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the dataset for inductor.
|
/// Get the dataset for inductor.
|
||||||
pub fn inductor(&self) -> &Dataset {
|
pub fn inductor_dataset(&self) -> &Dataset {
|
||||||
&self.inductor
|
&self.inductor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, TeError)]
|
#[derive(Debug, TeError)]
|
||||||
pub enum ParseHumanReadableValueError {
|
pub enum ParseHumanReadableValueError {
|
||||||
|
#[error("fail to parse floating point part of given human readable value: {0}")]
|
||||||
|
ParseFloat(#[from] ParseFloatError),
|
||||||
|
#[error("arithmetic error: {0}")]
|
||||||
|
BadArithmetic(#[from] FloatingPointError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert human readable value to float.
|
/// Convert human readable value to float.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// `strl` is the human readable value.
|
||||||
///
|
/// The return value is the parsed float value.
|
||||||
/// * `strl` - The human readable value.
|
/// or error occurs when parsing.
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// The parsed float value.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// Returns [`DatasetError::InvalidHumanReadableValue`] if the input string is not a valid number.
|
|
||||||
pub fn from_human_readable_value(strl: &str) -> Result<f64, ParseHumanReadableValueError> {
|
pub fn from_human_readable_value(strl: &str) -> Result<f64, ParseHumanReadableValueError> {
|
||||||
let strl = strl.trim();
|
let strl = strl.trim();
|
||||||
|
|
||||||
@@ -373,10 +381,8 @@ pub fn from_human_readable_value(strl: &str) -> Result<f64, ParseHumanReadableVa
|
|||||||
(strl, 1.0)
|
(strl, 1.0)
|
||||||
};
|
};
|
||||||
|
|
||||||
num_part
|
let num = num_part.parse::<f64>()?;
|
||||||
.parse::<f64>()
|
Ok(sanitize_floating_point(num * multiplier)?)
|
||||||
.map(|v| v * multiplier)
|
|
||||||
.map_err(|_| DatasetError::InvalidHumanReadableValue(strl.to_string()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The unit scale for human readable value.
|
/// The unit scale for human readable value.
|
||||||
@@ -395,13 +401,7 @@ pub enum UnitScale {
|
|||||||
|
|
||||||
/// Get the unit scale of human readable value.
|
/// Get the unit scale of human readable value.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// `v` is the value for analyzing scale.
|
||||||
///
|
|
||||||
/// * `v` - The value.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// The unit scale.
|
|
||||||
pub fn get_human_readable_value_scale(v: f64) -> UnitScale {
|
pub fn get_human_readable_value_scale(v: f64) -> UnitScale {
|
||||||
let v = v.abs();
|
let v = v.abs();
|
||||||
if v < 1e-12 {
|
if v < 1e-12 {
|
||||||
@@ -427,29 +427,21 @@ pub fn get_human_readable_value_scale(v: f64) -> UnitScale {
|
|||||||
|
|
||||||
/// Convert float value to human readable value.
|
/// Convert float value to human readable value.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// `v`is the float value for formatting as human readable value.
|
||||||
///
|
|
||||||
/// * `v` - The float value.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// The human readable value.
|
|
||||||
pub fn to_human_readable_value(v: f64) -> String {
|
pub fn to_human_readable_value(v: f64) -> String {
|
||||||
let scale = get_human_readable_value_scale(v);
|
let scale = get_human_readable_value_scale(v);
|
||||||
match scale {
|
match scale {
|
||||||
UnitScale::NanoLower => format!("{:+.4e} n", v / 1e-12),
|
UnitScale::NanoLower => format!("{:+.4e} n", v / 1e-12),
|
||||||
UnitScale::Nano => format!("{:+.4f} p", v / 1e-9),
|
UnitScale::Nano => format!("{:+.4} p", v / 1e-9),
|
||||||
UnitScale::Micro => format!("{:+.4f} u", v / 1e-6),
|
UnitScale::Micro => format!("{:+.4} u", v / 1e-6),
|
||||||
UnitScale::Milli => format!("{:+.4f} m", v / 1e-3),
|
UnitScale::Milli => format!("{:+.4} m", v / 1e-3),
|
||||||
UnitScale::None => {
|
// YYC MARK:
|
||||||
// YYC MARK:
|
// The space of this format string is by design
|
||||||
// The space of this format string is by design
|
// for keeping the same style with other format strings.
|
||||||
// for keeping the same style with other format strings.
|
UnitScale::None => format!("{:+.4} ", v),
|
||||||
format!("{:+.4} ", v)
|
UnitScale::Kilo => format!("{:+.4} k", v / 1e3),
|
||||||
}
|
UnitScale::Mega => format!("{:+.4} M", v / 1e6),
|
||||||
UnitScale::Kilo => format!("{:+.4f} k", v / 1e3),
|
UnitScale::Giga => format!("{:+.4} G", v / 1e9),
|
||||||
UnitScale::Mega => format!("{:+.4f} M", v / 1e6),
|
|
||||||
UnitScale::Giga => format!("{:+.4f} G", v / 1e9),
|
|
||||||
UnitScale::GigaHigher => format!("{:+.4e} G", v / 1e9),
|
UnitScale::GigaHigher => format!("{:+.4e} G", v / 1e9),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -440,9 +440,9 @@ impl BfsResolver {
|
|||||||
|
|
||||||
fn pick_dataset(&self, device_kind: DeviceKind) -> &Dataset {
|
fn pick_dataset(&self, device_kind: DeviceKind) -> &Dataset {
|
||||||
match device_kind {
|
match device_kind {
|
||||||
DeviceKind::Resistor => self.datasets.resistor(),
|
DeviceKind::Resistor => self.datasets.resistor_dataset(),
|
||||||
DeviceKind::Capacitor => self.datasets.capacitor(),
|
DeviceKind::Capacitor => self.datasets.capacitor_dataset(),
|
||||||
DeviceKind::Inductor => self.datasets.inductor(),
|
DeviceKind::Inductor => self.datasets.inductor_dataset(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ impl LutResolver {
|
|||||||
/// See [`LutItem::new`].
|
/// See [`LutItem::new`].
|
||||||
pub fn new(datasets: &DatasetCollection) -> Result<Self, LcrConnError> {
|
pub fn new(datasets: &DatasetCollection) -> Result<Self, LcrConnError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
resistor_lut: Self::build_lut(datasets.resistor(), DeviceKind::Resistor)?,
|
resistor_lut: Self::build_lut(datasets.resistor_dataset(), DeviceKind::Resistor)?,
|
||||||
capacitor_lut: Self::build_lut(datasets.capacitor(), DeviceKind::Capacitor)?,
|
capacitor_lut: Self::build_lut(datasets.capacitor_dataset(), DeviceKind::Capacitor)?,
|
||||||
inductor_lut: Self::build_lut(datasets.inductor(), DeviceKind::Inductor)?,
|
inductor_lut: Self::build_lut(datasets.inductor_dataset(), DeviceKind::Inductor)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user