fts_core/models/
demand.rs1mod constant;
2mod curve;
3
4pub use constant::{Constant, RawConstant};
5pub use curve::{Curve, Point};
6use serde::{Deserialize, Serialize};
7use thiserror::Error;
8use utoipa::ToSchema;
9
10#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ToSchema)]
18#[serde(untagged, try_from = "RawDemandCurve", into = "RawDemandCurve")]
19pub enum DemandCurve {
24 Curve(#[schema(inline)] Curve),
26 Constant(#[schema(inline)] Constant),
28}
29
30impl DemandCurve {
31 pub fn domain(&self) -> (f64, f64) {
33 match self {
34 Self::Constant(constant) => constant.domain(),
35 Self::Curve(curve) => curve.domain(),
36 }
37 }
38
39 pub fn as_solver(&self, scale: f64) -> Vec<fts_solver::Point> {
41 match self {
42 Self::Constant(constant) => constant.as_solver(scale),
43 Self::Curve(curve) => curve.as_solver(scale),
44 }
45 }
46}
47
48#[derive(Error, Debug)]
50pub enum ValidationError {
51 #[error("invalid demand curve: {0}")]
53 Curve(#[from] curve::ValidationError),
54 #[error("invalid constant curve: {0}")]
56 Constant(#[from] constant::ValidationError),
57}
58
59#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
63#[serde(untagged)]
64pub enum RawDemandCurve {
65 Curve(Vec<Point>),
67 Constant(RawConstant),
69}
70
71impl TryFrom<RawDemandCurve> for DemandCurve {
72 type Error = ValidationError;
73
74 fn try_from(value: RawDemandCurve) -> Result<Self, Self::Error> {
75 match value {
76 RawDemandCurve::Curve(curve) => Ok(DemandCurve::Curve(curve.try_into()?)),
77 RawDemandCurve::Constant(constant) => Ok(DemandCurve::Constant(constant.try_into()?)),
78 }
79 }
80}
81
82impl From<DemandCurve> for RawDemandCurve {
83 fn from(value: DemandCurve) -> Self {
84 match value {
85 DemandCurve::Curve(curve) => RawDemandCurve::Curve(curve.into()),
86 DemandCurve::Constant(constant) => RawDemandCurve::Constant(constant.into()),
87 }
88 }
89}