Skip to content

Commit

Permalink
feat(parse): add proto::PlanVersion parser (#165)
Browse files Browse the repository at this point in the history
A parser for `proto::PlanVersion`, it parses iff the version is not
missing and the version parses.
  • Loading branch information
mbrobbel authored Mar 19, 2024
1 parent 6f3eb94 commit 8b648c9
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 6 deletions.
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ jobs:
${{ runner.os }}-cargo-
- run: cargo-smart-release --debug --locked || true
- run: cargo check --all-features
- run: cargo changelog --execute substrait
- run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
Expand Down
14 changes: 13 additions & 1 deletion src/parse/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,23 @@

//! A parse context.

use crate::parse::Parse;

/// A parse context.
///
/// Parsing Substrait data is context-sensitive. This trait provides methods
/// that can be used by parser implementations to parse Substrait data.
pub trait Context {}
pub trait Context {
/// Parse an item with this context.
///
/// See [Parse::parse].
fn parse<T: Parse<Self>>(&mut self, item: T) -> Result<T::Parsed, T::Error>
where
Self: Sized,
{
item.parse(self)
}
}

#[cfg(test)]
pub(crate) mod tests {
Expand Down
3 changes: 3 additions & 0 deletions src/parse/proto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@

mod version;
pub use version::{Version, VersionError};

mod plan_version;
pub use plan_version::{PlanVersion, PlanVersionError};
105 changes: 105 additions & 0 deletions src/parse/proto/plan_version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: Apache-2.0

//! Parsing of [proto::PlanVersion].

use crate::{
parse::{context::Context, proto::Version, Parse},
proto,
};
use thiserror::Error;

use super::VersionError;

/// A parsed [proto::PlanVersion].
#[derive(Clone, Debug, PartialEq)]
pub struct PlanVersion {
/// The version of the plan.
version: Version,
}

impl PlanVersion {
/// Returns the version of this plan version.
///
/// See [proto::PlanVersion::version].
pub fn version(&self) -> &Version {
&self.version
}
}

/// Parse errors for [proto::PlanVersion].
#[derive(Debug, Error, PartialEq)]
pub enum PlanVersionError {
/// Version is missing.
#[error("version must be specified")]
Missing,

/// Version error.
#[error("version must be valid")]
Version(#[from] VersionError),
}

impl<C: Context> Parse<C> for proto::PlanVersion {
type Parsed = PlanVersion;
type Error = PlanVersionError;

fn parse(self, ctx: &mut C) -> Result<Self::Parsed, Self::Error> {
let proto::PlanVersion { version } = self;

// The version is required, and must be valid.
let version = version
.map(|version| ctx.parse(version))
.transpose()?
.ok_or(PlanVersionError::Missing)?;

let plan_version = PlanVersion { version };

Ok(plan_version)
}
}

impl From<PlanVersion> for proto::PlanVersion {
fn from(plan_version: PlanVersion) -> Self {
let PlanVersion { version } = plan_version;

proto::PlanVersion {
version: Some(version.into()),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{
parse::{context::tests::Context, proto::VersionError},
version,
};

#[test]
fn parse() {
let plan_version = proto::PlanVersion {
version: Some(version::version()),
};
assert!(plan_version.parse(&mut Context::default()).is_ok());
}

#[test]
fn missing() {
let plan_version = proto::PlanVersion::default();
assert_eq!(
plan_version.parse(&mut Context::default()),
Err(PlanVersionError::Missing)
);
}

#[test]
fn version_error() {
let plan_version = proto::PlanVersion {
version: Some(proto::Version::default()),
};
assert_eq!(
plan_version.parse(&mut Context::default()),
Err(PlanVersionError::Version(VersionError::Missing))
);
}
}
13 changes: 11 additions & 2 deletions src/parse/proto/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

//! Parsing of [proto::Version].

use crate::parse::{context::Context, Parse};
use crate::{proto, version};
use crate::{
parse::{context::Context, Parse},
proto, version,
};
use hex::FromHex;
use thiserror::Error;

Expand All @@ -22,16 +24,23 @@ pub struct Version {

impl Version {
/// Returns the semantic version of this version.
///
/// See [proto::Version::major_number], [proto::Version::minor_number] and
/// [proto::Version::patch_number].
pub fn version(&self) -> &semver::Version {
&self.version
}

/// Returns the git hash of this version.
///
/// See [proto::Version::git_hash].
pub fn git_hash(&self) -> Option<&[u8; 20]> {
self.git_hash.as_ref()
}

/// Returns the producer of this version.
///
/// See [proto::Version::producer].
pub fn producer(&self) -> Option<&str> {
self.producer.as_deref()
}
Expand Down
2 changes: 1 addition & 1 deletion src/proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
clippy::needless_borrows_for_generic_args
)]

//! Generated types for the protobuf `substrait` package
//! Generated types for the protobuf `substrait` package.

/// Generated types for the protobuf `substrait.extensions` package
pub mod extensions {
Expand Down
2 changes: 1 addition & 1 deletion src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
unused_variables
)]

//! Generated types for text-based definitions
//! Generated types for text-based definitions.

// https://github.com/oxidecomputer/typify/issues/245
include!(concat!(env!("OUT_DIR"), "/substrait_text.rs"));
Expand Down

0 comments on commit 8b648c9

Please sign in to comment.