substrait/parse/proto/extensions/
simple_extension_urn.rs1use std::str::FromStr;
6
7use thiserror::Error;
8
9use crate::{
10 parse::{Anchor, Context, Parse, context::ContextError},
11 proto,
12 urn::{InvalidUrn, Urn},
13};
14
15#[derive(Clone, Debug, PartialEq)]
17pub struct SimpleExtensionUrn {
18 urn: Urn,
20
21 anchor: Anchor<Self>,
23}
24
25impl SimpleExtensionUrn {
26 pub fn urn(&self) -> &Urn {
30 &self.urn
31 }
32
33 pub fn anchor(&self) -> Anchor<Self> {
37 self.anchor
38 }
39}
40
41#[derive(Debug, Error, PartialEq)]
43pub enum SimpleExtensionUrnError {
44 #[error("invalid urn")]
46 InvalidUrn(#[from] InvalidUrn),
47
48 #[error(transparent)]
50 Context(#[from] ContextError),
51}
52
53impl<C: Context> Parse<C> for proto::extensions::SimpleExtensionUrn {
54 type Parsed = SimpleExtensionUrn;
55 type Error = SimpleExtensionUrnError;
56
57 fn parse(self, ctx: &mut C) -> Result<Self::Parsed, Self::Error> {
58 let proto::extensions::SimpleExtensionUrn {
59 extension_urn_anchor: anchor,
60 urn,
61 } = self;
62
63 let urn = Urn::from_str(&urn)?;
65
66 let simple_extension_urn = SimpleExtensionUrn {
68 urn,
69 anchor: Anchor::new(anchor),
70 };
71
72 ctx.add_simple_extension_urn(&simple_extension_urn)?;
75
76 Ok(simple_extension_urn)
77 }
78}
79
80impl From<SimpleExtensionUrn> for proto::extensions::SimpleExtensionUrn {
81 fn from(simple_extension_urn: SimpleExtensionUrn) -> Self {
82 let SimpleExtensionUrn { urn, anchor } = simple_extension_urn;
83 proto::extensions::SimpleExtensionUrn {
84 urn: urn.to_string(),
85 extension_urn_anchor: anchor.into_inner(),
86 }
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use crate::parse::{Context as _, context::tests::Context};
94
95 #[test]
96 fn parse() -> Result<(), SimpleExtensionUrnError> {
97 let simple_extension_urn = proto::extensions::SimpleExtensionUrn {
98 extension_urn_anchor: 1,
99 urn: "extension:substrait-rs:test".to_string(),
100 };
101 let simple_extension_urn = simple_extension_urn.parse(&mut Context::default())?;
102 assert_eq!(simple_extension_urn.anchor(), Anchor::new(1));
103 assert_eq!(
104 simple_extension_urn.urn().to_string().as_str(),
105 "extension:substrait-rs:test"
106 );
107 Ok(())
108 }
109
110 #[test]
111 fn invalid_urn() {
112 let simple_extension_urn = proto::extensions::SimpleExtensionUrn::default();
113 assert_eq!(
114 simple_extension_urn.parse(&mut Context::default()),
115 Err(SimpleExtensionUrnError::InvalidUrn(InvalidUrn))
116 );
117 let simple_extension_urn = proto::extensions::SimpleExtensionUrn {
118 extension_urn_anchor: 1,
119 urn: "urn::".to_string(),
120 };
121 assert_eq!(
122 simple_extension_urn.parse(&mut Context::default()),
123 Err(SimpleExtensionUrnError::InvalidUrn(InvalidUrn))
124 );
125 }
126
127 #[test]
128 fn duplicate_simple_extension() {
129 let mut ctx = Context::default();
130 let simple_extension_urn = proto::extensions::SimpleExtensionUrn {
131 extension_urn_anchor: 1,
132 urn: "extension:substrait-rs:test".to_string(),
133 };
134 assert!(ctx.parse(simple_extension_urn.clone()).is_ok());
135 assert_eq!(
136 ctx.parse(simple_extension_urn),
137 Err(SimpleExtensionUrnError::Context(
138 ContextError::DuplicateSimpleExtension(Anchor::new(1))
139 ))
140 );
141 }
142}