mabel_eno/queries/
embed_query.rs1use std::str::FromStr;
2
3use crate::elements::{Document, Element, Embed, EmbedImpl, Section};
4use crate::queries::{SectionQuery, SectionQueryImpl};
5use crate::{Error, Printer};
6
7pub struct EmbedQuery<'a> {
8 element_option: Option<&'a Embed>,
9 key: Option<String>,
10 parent: EmbedQueryParent<'a>,
11}
12
13pub trait EmbedQueryImpl<'a> {
14 #[allow(clippy::new_ret_no_self)]
15 fn new(
16 element_option: Option<&'a Embed>,
17 key: Option<String>,
18 parent: EmbedQueryParent<'a>,
19 ) -> EmbedQuery<'a>;
20}
21
22pub enum EmbedQueryParent<'a> {
23 Document(&'a Document),
24 Section(&'a Section),
25 SectionQuery(&'a SectionQuery<'a>),
26}
27
28impl<'a> EmbedQuery<'a> {
29 pub fn missing_error(&self) -> Error {
30 match self.parent {
31 EmbedQueryParent::Document(_) => Error::new(
32 format!(
33 "Embed {} not found",
34 self.key.as_deref().unwrap_or("(can have any key)")
35 ),
36 Document::LINE_NUMBER,
37 ),
38 EmbedQueryParent::Section(section) => Error::new(
39 format!(
40 "Embed {} not found",
41 self.key.as_deref().unwrap_or("(can have any key)")
42 ),
43 section.line_number,
44 ),
45 EmbedQueryParent::SectionQuery(section_query) => match section_query.element() {
46 Some(section) => Error::new(
47 format!(
48 "Embed {} not found",
49 self.key.as_deref().unwrap_or("(can have any key)")
50 ),
51 section.line_number,
52 ),
53 None => section_query.missing_error(),
54 },
55 }
56 }
57
58 pub fn optional_value(&self) -> Result<Option<String>, Error> {
59 match &self.element_option {
60 Some(embed) => match &embed.get_value() {
61 Some(value) => Ok(Some(value.to_string())),
62 None => Ok(None),
63 },
64 None => Err(self.missing_error()),
65 }
66 }
67
68 pub fn required_value<T: FromStr>(&self) -> Result<T, Error>
69 where
70 <T as FromStr>::Err: std::fmt::Display,
71 {
72 match &self.element_option {
73 Some(embed) => match &embed.get_value() {
74 Some(value) => match value.parse::<T>() {
75 Ok(converted) => Ok(converted),
76 Err(err) => Err(Error::new(format!("{}", err), embed.line_number)),
77 },
78 None => Err(Error::new("Missing value".to_string(), embed.line_number)),
79 },
80 None => Err(self.missing_error()),
81 }
82 }
83
84 pub fn snippet(&self) -> Result<String, Error> {
85 match self.element_option {
86 Some(embed) => Ok(embed.snippet()),
87 None => Err(self.missing_error()),
88 }
89 }
90
91 pub fn snippet_with_options(
92 &self,
93 printer: &dyn Printer,
94 gutter: bool,
95 ) -> Result<String, Error> {
96 match self.element_option {
97 Some(embed) => Ok(embed.snippet_with_options(printer, gutter)),
98 None => Err(self.missing_error()),
99 }
100 }
101}
102
103impl<'a> EmbedQueryImpl<'a> for EmbedQuery<'a> {
104 fn new(
105 element_option: Option<&'a Embed>,
106 key: Option<String>,
107 parent: EmbedQueryParent<'a>,
108 ) -> EmbedQuery<'a> {
109 EmbedQuery {
110 element_option,
111 key,
112 parent,
113 }
114 }
115}