taitan_orm_parser/template_parser/structs/atomics/
atomic_stream.rs1use crate::template_parser::structs::atomics::generic_atomic::GenericAtomic;
2use crate::template_parser::structs::atomics::atomic_trait::AtomicTrait;
3use crate::Atomic;
4use nom::character::complete::multispace0;
5use nom::sequence::preceded;
6use std::fmt::Debug;
7use taitan_orm_tracing::debug;
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct GenericAtomicStream {
11 pub atomics: Vec<GenericAtomic>,
12}
13
14impl GenericAtomicStream {
15 pub fn parse<T>(input: &str) -> Result<Self, String>
16 where
17 T: AtomicTrait + Clone + PartialEq + Debug + Into<GenericAtomic>,
18 {
19 let atomics = AtomicStream::<T>::parse(input)?;
20 let generic_atomics: Vec<GenericAtomic> =
21 atomics.atomics.into_iter().map(Into::into).collect();
22 Ok(GenericAtomicStream {
23 atomics: generic_atomics,
24 })
25 }
26}
27
28#[derive(Debug, Clone, PartialEq)]
29pub struct AtomicStream<T: AtomicTrait + Clone + PartialEq + Debug> {
30 pub atomics: Vec<T>,
31}
32
33impl<T> AtomicStream<T>
34where
35 T: AtomicTrait + Clone + PartialEq + Debug,
36{
37 pub fn parse(input: &str) -> Result<Self, String> {
38 debug!("SqlTemplate::parse({})", input);
39 let mut atomics = Vec::new();
40 let mut remainder = input;
41 loop {
42 let parse_result = preceded(multispace0, T::parse)(remainder);
43 match parse_result {
44 Ok((remaining, parsed)) => {
45 debug!("SqlTemplate::parse({})->{:?}", remaining, parsed);
46 atomics.push(parsed);
47 remainder = remaining;
48 }
49 Err(err_msg) => {
50 debug!("SqlTemplate::parse error: {}", err_msg);
51 let err_msg = format!("failed to parse atomic: {}", input);
52 return Err(err_msg);
53 }
54 }
55
56 if remainder.is_empty() {
57 break;
58 }
59 }
60 Ok(AtomicStream { atomics })
61 }
62}