1use serde::{Deserialize, Serialize};
4
5use crate::error::MotorError;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct ParseWarning {
10 pub line: usize,
12 pub kind: WarningKind,
14 pub message: String,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
20#[serde(rename_all = "snake_case")]
21#[non_exhaustive]
22pub enum WarningKind {
23 Skipped,
25 Dropped,
27 Unusual,
29}
30
31impl ParseWarning {
32 pub(crate) fn new(line: usize, kind: WarningKind, message: impl Into<String>) -> Self {
33 Self {
34 line,
35 kind,
36 message: message.into(),
37 }
38 }
39}
40
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
43pub struct Parsed<T> {
44 pub value: T,
46 pub warnings: Vec<ParseWarning>,
48}
49
50pub(crate) fn finite(text: &str, what: &'static str) -> Result<f64, MotorError> {
52 match text.trim().parse::<f64>() {
53 Ok(value) if value.is_finite() => Ok(value),
54 _ => Err(MotorError::Parse {
55 what,
56 text: text.to_owned(),
57 }),
58 }
59}
60
61pub(crate) fn check_writable(
63 value: f64,
64 what: &'static str,
65 non_negative: bool,
66) -> Result<(), MotorError> {
67 if value.is_finite() && !(non_negative && value < 0.0) {
68 Ok(())
69 } else {
70 Err(MotorError::Domain { what, value })
71 }
72}