substrait/parse/proto/
plan_version.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Parsing of [proto::PlanVersion].
4
5use crate::{parse::proto::Version, proto};
6use thiserror::Error;
7
8use super::VersionError;
9
10/// A parsed [proto::PlanVersion].
11#[derive(Clone, Debug, PartialEq)]
12pub struct PlanVersion {
13    /// The version of the plan.
14    version: Version,
15}
16
17impl PlanVersion {
18    /// Returns the version of this plan version.
19    ///
20    /// See [proto::PlanVersion::version].
21    pub fn version(&self) -> &Version {
22        &self.version
23    }
24}
25
26/// Parse errors for [proto::PlanVersion].
27#[derive(Debug, Error, PartialEq)]
28pub enum PlanVersionError {
29    /// Version is missing.
30    #[error("version must be specified")]
31    Missing,
32
33    /// Version error.
34    #[error("version must be valid")]
35    Version(#[from] VersionError),
36}
37
38impl TryFrom<proto::PlanVersion> for PlanVersion {
39    type Error = PlanVersionError;
40
41    fn try_from(value: proto::PlanVersion) -> Result<Self, Self::Error> {
42        let proto::PlanVersion { version } = value;
43
44        // The version is required, and must be valid.
45        let version = version
46            .map(Version::try_from)
47            .transpose()?
48            .ok_or(PlanVersionError::Missing)?;
49
50        let plan_version = PlanVersion { version };
51
52        Ok(plan_version)
53    }
54}
55
56impl From<PlanVersion> for proto::PlanVersion {
57    fn from(plan_version: PlanVersion) -> Self {
58        let PlanVersion { version } = plan_version;
59
60        proto::PlanVersion {
61            version: Some(version.into()),
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use crate::{parse::proto::VersionError, version};
70
71    #[test]
72    fn parse() -> Result<(), PlanVersionError> {
73        let plan_version = proto::PlanVersion {
74            version: Some(version::version()),
75        };
76        PlanVersion::try_from(plan_version)?;
77        Ok(())
78    }
79
80    #[test]
81    fn missing() {
82        let plan_version = proto::PlanVersion::default();
83        assert_eq!(
84            PlanVersion::try_from(plan_version),
85            Err(PlanVersionError::Missing)
86        );
87    }
88
89    #[test]
90    fn version_error() {
91        let plan_version = proto::PlanVersion {
92            version: Some(proto::Version::default()),
93        };
94        assert_eq!(
95            PlanVersion::try_from(plan_version),
96            Err(PlanVersionError::Version(VersionError::Missing))
97        );
98    }
99}