From 40da8397a78f5bed7d28f64072714f3e4b66a66c Mon Sep 17 00:00:00 2001 From: fxpineau Date: Tue, 12 Dec 2023 08:52:34 +0100 Subject: [PATCH] Modify visitor and implement 'void' and 'echo' visitors --- README.md | 5 +- src/space/common/region.rs | 9 +- src/space/expression.rs | 24 ++-- src/space/geometry.rs | 32 +++-- src/visitor/impls/donothing.rs | 25 ++-- src/visitor/impls/echo.rs | 239 +++++++++++++++++++++++++++++++++ src/visitor/mod.rs | 75 +++++++++-- 7 files changed, 357 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 8c4d2bb..0a59f91 100644 --- a/README.md +++ b/README.md @@ -310,8 +310,9 @@ is converted into: * [ ] Make a JS/Wasm library. * [X] Add everywhere builders, getters and setters like in the `FillFrameRefposFlavor` structure to make a clean API. * [X] Create a visitor. - + [X] implement an 'empty' visitor - + [ ] implement an 'echo' visitor + + [X] implement an `empty` visitor + + [X] implement an `echo` visitor + + [X] implement a `stcs2moc` visitor (available in [MOCLibRust](https://github.com/cds-astro/cds-moc-rust)) * [ ] Implement `fold` to avoid too wide lines. * [ ] Support for STC XML serialization/deserialization? diff --git a/src/space/common/region.rs b/src/space/common/region.rs index 745a6c5..1457ac3 100644 --- a/src/space/common/region.rs +++ b/src/space/common/region.rs @@ -126,15 +126,10 @@ pub trait RegionParams: Sized + Display { #[derive(Serialize, Deserialize, Default, Debug, PartialEq)] pub struct AllSkyParams; -/*impl AllSkyParams { - pub fn new() -> Self { - Self - } -}*/ impl RegionParams for AllSkyParams { const REGION_NAME: &'static str = "AllSky"; fn accept(&self, visitor: &mut V) -> Result { - visitor.visit_allsky(self) + visitor.visit_allsky() } fn parse<'a, E: NomErr<'a>>(input: &'a str) -> IResult<&'a str, Self, E> { Ok((input, Self)) @@ -172,7 +167,7 @@ impl RegionParams for CircleParams { } fn parse<'a, E: NomErr<'a>>(input: &'a str) -> IResult<&'a str, Self, E> { map( - many_m_n(2, usize::MAX, preceded(multispace1, double)), + many_m_n(3, usize::MAX, preceded(multispace1, double)), |pos_and_radius| { let (radius, pos) = pos_and_radius.split_last().unwrap(); let radius = *radius; diff --git a/src/space/expression.rs b/src/space/expression.rs index 29f024d..7e29d2a 100644 --- a/src/space/expression.rs +++ b/src/space/expression.rs @@ -220,8 +220,12 @@ impl Expression { self.post.pixsize() } - fn accept_gen(&self) -> Result { - V::C::new_from_params(&self.pre, &self.post) + fn accept_gen( + &self, + visitor: &mut V, + ) -> Result<::Value, V::Error> { + visitor + .new_compound_visitor(&self.pre, &self.post) .and_then(|mut visitor| self.args.accept(&mut visitor)) } @@ -258,9 +262,9 @@ impl Expression { pub fn elem(&self) -> &RegionOrExpr { self.args.elem() } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_not(res)) } } @@ -278,9 +282,9 @@ impl Expression { pub fn right_elem(&self) -> &RegionOrExpr { self.args.right_elem() } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_difference(res)) } } @@ -291,9 +295,9 @@ impl Expression { pub fn elems(&self) -> &[RegionOrExpr] { self.args.elems() } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_union(res)) } } @@ -304,9 +308,9 @@ impl Expression { pub fn elems(&self) -> &[RegionOrExpr] { self.args.elems() } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_intersection(res)) } } diff --git a/src/space/geometry.rs b/src/space/geometry.rs index d266b2a..e968843 100644 --- a/src/space/geometry.rs +++ b/src/space/geometry.rs @@ -238,8 +238,12 @@ impl Geometry { self.post.pixsize() } - fn accept_gen(&self) -> Result { - V::C::new_from_params(&self.pre, &self.post) + fn accept_gen( + &self, + visitor: &mut V, + ) -> Result<::Value, V::Error> { + visitor + .new_compound_visitor(&self.pre, &self.post) .and_then(|mut visitor| self.params.accept(&mut visitor)) } @@ -273,9 +277,9 @@ impl Geometry { pub fn flavor_or_default(&self) -> Flavor { self.pre.flavor().unwrap_or(Flavor::Spher2) } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_allsky(res)) } } @@ -292,9 +296,9 @@ impl Geometry { pub fn flavor_or_default(&self) -> Flavor { self.pre.flavor().unwrap_or(Flavor::Spher2) } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_circle(res)) } } @@ -326,9 +330,9 @@ impl Geometry { pub fn flavor_or_default(&self) -> Flavor { self.pre.flavor().unwrap_or(Flavor::Spher2) } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_ellipse(res)) } } @@ -346,9 +350,9 @@ impl Geometry { pub fn flavor_or_default(&self) -> Flavor { self.pre.flavor().unwrap_or(Flavor::Spher2) } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_box(res)) } } @@ -363,9 +367,9 @@ impl Geometry { pub fn flavor_or_default(&self) -> Flavor { self.pre.flavor().unwrap_or(Flavor::Spher2) } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_polygon(res)) } } @@ -380,9 +384,9 @@ impl Geometry { pub fn flavor_or_default(&self) -> Flavor { self.pre.flavor().unwrap_or(Flavor::UnitSpher) } - pub fn accept(&self, visitor: V) -> Result { + pub fn accept(&self, mut visitor: V) -> Result { self - .accept_gen::() + .accept_gen(&mut visitor) .and_then(|res| visitor.visit_convex(res)) } } diff --git a/src/visitor/impls/donothing.rs b/src/visitor/impls/donothing.rs index 50e4e8d..7941266 100644 --- a/src/visitor/impls/donothing.rs +++ b/src/visitor/impls/donothing.rs @@ -1,11 +1,13 @@ -use std::error::Error; -use std::fmt::{Display, Formatter}; +use std::{ + error::Error, + fmt::{Display, Formatter}, +}; use crate::{ redshift::{RedshiftInterval, RedshiftValue}, space::{ common::{ - region::{AllSkyParams, BoxParams, CircleParams, ConvexParams, EllipseParams, PolygonParams}, + region::{BoxParams, CircleParams, ConvexParams, EllipseParams, PolygonParams}, FillFrameRefposFlavor, FromPosToVelocity, }, position::Position, @@ -94,14 +96,7 @@ impl CompoundVisitor for VoidVisitor { type Value = (); type Error = VoidError; - fn new_from_params( - _fill_fram_refpos_flavor: &FillFrameRefposFlavor, - _from_pos_to_velocity: &FromPosToVelocity, - ) -> Result { - Ok(Self) - } - - fn visit_allsky(&mut self, _allsky: &AllSkyParams) -> Result { + fn visit_allsky(&mut self) -> Result { Ok(()) } @@ -157,6 +152,14 @@ impl SpaceVisitor for VoidVisitor { type Error = VoidError; type C = Self; + fn new_compound_visitor( + &self, + _fill_fram_refpos_flavor: &FillFrameRefposFlavor, + _from_pos_to_velocity: &FromPosToVelocity, + ) -> Result { + Ok(Self) + } + fn visit_position_simple(self, _position: &Position) -> Result { Ok(()) } diff --git a/src/visitor/impls/echo.rs b/src/visitor/impls/echo.rs index e69de29..96b4c8d 100644 --- a/src/visitor/impls/echo.rs +++ b/src/visitor/impls/echo.rs @@ -0,0 +1,239 @@ +use std::{ + error::Error, + fmt::{Display, Formatter}, +}; + +use crate::{ + redshift::{RedshiftInterval, RedshiftValue}, + space::{ + common::{ + region::{BoxParams, CircleParams, ConvexParams, EllipseParams, PolygonParams}, + FillFrameRefposFlavor, FromPosToVelocity, + }, + position::Position, + positioninterval::PositionInterval, + }, + spectral::{SpecInterval, SpecValue}, + time::{TimeElem, TimeIntervalArgs, TimeSimple, TimeStartArgs, TimeStopArgs}, + visitor::{CompoundVisitor, RedshiftVisitor, SpaceVisitor, SpectralVisitor, TimeVisitor}, +}; + +#[derive(Debug)] +pub struct VoidError; + +impl Display for VoidError { + fn fmt(&self, _f: &mut Formatter<'_>) -> std::fmt::Result { + Ok(()) + } +} + +impl Error for VoidError {} + +/// Dummy implementation of `TimeVisitor` doing... nothing +/// (to be used when we are not interested in the Time part in a STC-S string). +pub struct EchoVisitor; + +impl TimeVisitor for EchoVisitor { + type Value = (); + type Error = VoidError; + + fn visit_time_simple(self, time: &TimeSimple) -> Result { + println!("visit time simple: {}", time.to_string()); + Ok(()) + } + + fn visit_time_interval( + self, + time_interval: &TimeElem, + ) -> Result { + println!("visit time interval: {}", time_interval.to_string()); + Ok(()) + } + + fn visit_time_start( + self, + time_start: &TimeElem, + ) -> Result { + println!("visit time start: {}", time_start.to_string()); + Ok(()) + } + + fn visit_time_stop(self, time_stop: &TimeElem) -> Result { + println!("visit time stop: {}", time_stop.to_string()); + Ok(()) + } +} + +impl SpectralVisitor for EchoVisitor { + type Value = (); + type Error = VoidError; + + fn visit_spectral_simple(self, value: &SpecValue) -> Result { + println!("visit spectral simple: {}", value.to_string()); + Ok(()) + } + + fn visit_spectral_interval(self, interval: &SpecInterval) -> Result { + println!("visit spectral interval: {}", interval.to_string()); + Ok(()) + } +} + +impl RedshiftVisitor for EchoVisitor { + type Value = (); + type Error = VoidError; + + fn visit_redshift_simple(self, redshift: &RedshiftValue) -> Result { + println!("visit redshift simple: {}", redshift.to_string()); + Ok(()) + } + + fn visit_redshift_interval( + self, + redshift_interval: &RedshiftInterval, + ) -> Result { + println!("visit redshift interval: {}", redshift_interval.to_string()); + Ok(()) + } +} + +impl CompoundVisitor for EchoVisitor { + type Value = (); + type Error = VoidError; + + fn visit_allsky(&mut self) -> Result { + println!(" * cvisit allsky"); + Ok(()) + } + + fn visit_circle(&mut self, circle: &CircleParams) -> Result { + println!(" * cvisit circle: {}", circle); + Ok(()) + } + + fn visit_ellipse(&mut self, ellipse: &EllipseParams) -> Result { + println!(" * cvisit ellipse: {}", ellipse); + Ok(()) + } + + fn visit_box(&mut self, skybox: &BoxParams) -> Result { + println!(" * cvisit box: {}", skybox); + Ok(()) + } + + fn visit_polygon(&mut self, polygon: &PolygonParams) -> Result { + println!(" * cvisit polygon: {}", polygon); + Ok(()) + } + + fn visit_convex(&mut self, convex: &ConvexParams) -> Result { + println!(" * cvisit convex: {}", convex); + Ok(()) + } + + fn visit_not(&mut self, _: Self::Value) -> Result { + println!(" * cvisit not"); + Ok(()) + } + + fn visit_union(&mut self, _: Vec) -> Result { + println!(" * cvisit union"); + Ok(()) + } + + fn visit_intersection(&mut self, _: Vec) -> Result { + println!(" * cvisit intersection"); + Ok(()) + } + + fn visit_difference( + &mut self, + _: Self::Value, + _: Self::Value, + ) -> Result { + println!(" * cvisit difference"); + Ok(()) + } +} + +impl SpaceVisitor for EchoVisitor { + type Value = (); + type Error = VoidError; + type C = Self; + + fn new_compound_visitor( + &self, + fill_fram_refpos_flavor: &FillFrameRefposFlavor, + from_pos_to_velocity: &FromPosToVelocity, + ) -> Result { + println!( + "get new compound visitor from params: {}{}", + fill_fram_refpos_flavor.to_string(), + from_pos_to_velocity.to_string() + ); + Ok(Self) + } + + fn visit_position_simple(self, position: &Position) -> Result { + println!("visit position simple: {}", position.to_string()); + Ok(()) + } + + fn visit_position_interval( + self, + interval: &PositionInterval, + ) -> Result { + println!("visit position interval: {}", interval.to_string()); + Ok(()) + } + + fn visit_allsky(self, _: Self::Value) -> Result { + println!("visit allsky"); + Ok(()) + } + + fn visit_circle(self, _: Self::Value) -> Result { + println!("visit circle"); + Ok(()) + } + + fn visit_ellipse(self, _: Self::Value) -> Result { + println!("visit ellipse"); + Ok(()) + } + + fn visit_box(self, _: Self::Value) -> Result { + println!("visit box"); + Ok(()) + } + + fn visit_polygon(self, _: Self::Value) -> Result { + println!("visit polygon"); + Ok(()) + } + + fn visit_convex(self, _: Self::Value) -> Result { + println!("visit convex"); + Ok(()) + } + + fn visit_not(self, _: Self::Value) -> Result { + println!("visit not"); + Ok(()) + } + + fn visit_union(self, _: Self::Value) -> Result { + println!("visit union"); + Ok(()) + } + + fn visit_intersection(self, _: Self::Value) -> Result { + println!("visit intersection"); + Ok(()) + } + + fn visit_difference(self, _: Self::Value) -> Result { + println!("visit difference"); + Ok(()) + } +} diff --git a/src/visitor/mod.rs b/src/visitor/mod.rs index 5648c68..573d7f9 100644 --- a/src/visitor/mod.rs +++ b/src/visitor/mod.rs @@ -4,7 +4,7 @@ use crate::{ redshift::{RedshiftInterval, RedshiftValue}, space::{ common::{ - region::{AllSkyParams, BoxParams, CircleParams, ConvexParams, EllipseParams, PolygonParams}, + region::{BoxParams, CircleParams, ConvexParams, EllipseParams, PolygonParams}, FillFrameRefposFlavor, FromPosToVelocity, }, position::Position, @@ -91,12 +91,7 @@ pub trait CompoundVisitor: Sized { /// Type of the returned error. type Error: Error; - fn new_from_params( - fill_fram_refpos_flavor: &FillFrameRefposFlavor, - from_pos_to_velocity: &FromPosToVelocity, - ) -> Result; - - fn visit_allsky(&mut self, allsky: &AllSkyParams) -> Result; + fn visit_allsky(&mut self) -> Result; fn visit_circle(&mut self, circle: &CircleParams) -> Result; fn visit_ellipse(&mut self, ellipse: &EllipseParams) -> Result; fn visit_box(&mut self, skybox: &BoxParams) -> Result; @@ -121,10 +116,74 @@ pub trait CompoundVisitor: Sized { /// When visiting a single `Stc` structure, at most one of the 12 methods is called. pub trait SpaceVisitor: Sized { + type Value; + type Error: Error; + type C: CompoundVisitor; + + fn new_compound_visitor( + &self, + fill_fram_refpos_flavor: &FillFrameRefposFlavor, + from_pos_to_velocity: &FromPosToVelocity, + ) -> Result; + + fn visit_position_simple(self, position: &Position) -> Result; + fn visit_position_interval(self, interval: &PositionInterval) + -> Result; + + fn visit_allsky( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_circle( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_ellipse( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_box( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_polygon( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_convex( + self, + content_visit_result: ::Value, + ) -> Result; + + fn visit_not( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_union( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_intersection( + self, + content_visit_result: ::Value, + ) -> Result; + fn visit_difference( + self, + content_visit_result: ::Value, + ) -> Result; +} + +/*pub trait SpaceVisitor: Sized { type Value; type Error: Error; type C: CompoundVisitor; + fn new_compound_visitor( + &self, + fill_fram_refpos_flavor: &FillFrameRefposFlavor, + from_pos_to_velocity: &FromPosToVelocity, + ) -> Result; + fn visit_position_simple(self, position: &Position) -> Result; fn visit_position_interval(self, interval: &PositionInterval) -> Result; @@ -143,7 +202,7 @@ pub trait SpaceVisitor: Sized { content_visit_result: Self::Value, ) -> Result; fn visit_difference(self, content_visit_result: Self::Value) -> Result; -} +}*/ /// When visiting a single `Stc` structure, at most one of the two methods is called. pub trait RedshiftVisitor: Sized {