substrait/parse/proto/
plan_version.rs

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