gen_parser/ast/
script.rs

1use std::fmt::Display;
2
3use gen_utils::error::{Error, ParseError};
4use quote::quote;
5use syn::Block;
6
7use crate::target::parse_script;
8
9/// # Script
10/// which is from `.gen` file, in `.gen` file, people can write rust code or ets code
11/// - `<script lang="rust">` or `<script>` is rust code (default is rust code for makepad framework)
12/// - ~`<script lang="ets">` is ets code (ets is now for ark HarmonyOs)~
13/// ---
14/// if is rust code use Block to store, otherwise use String to store
15#[derive(Debug, Clone, PartialEq)]
16pub enum Script {
17    /// rust code
18    Rs(Block),
19    Other {
20        lang: String,
21        code: String,
22    },
23}
24
25#[allow(dead_code)]
26impl Script {
27    /// is current script is empty or not
28    pub fn is_empty(&self) -> bool {
29        match self {
30            Script::Rs(block) => block.stmts.is_empty(),
31            Script::Other { code, .. } => code.is_empty(),
32        }
33    }
34}
35
36impl From<Block> for Script {
37    fn from(value: Block) -> Self {
38        Script::Rs(value)
39    }
40}
41
42impl TryFrom<(&str, Option<String>)> for Script {
43    type Error = Error;
44
45    fn try_from(value: (&str, Option<String>)) -> Result<Self, Self::Error> {
46        match value.1.as_ref() {
47            Some(lang) => match lang.as_str() {
48                "rust" | "rs" => {
49                    let code =
50                        parse_script(value.0)?;
51                    Ok(Script::Rs(code))
52                }
53                other => Ok(Script::Other {
54                    lang: other.to_string(),
55                    code: value.0.to_string(),
56                }),
57            },
58            None => Err(ParseError::template("the tag must be script, current is not").into()),
59        }
60    }
61}
62
63impl Display for Script {
64    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65        match self {
66            Script::Rs(rs) => {
67                // if is rust code use quote to format
68                let res = quote! {
69                    #rs
70                };
71                // remove `{}`
72                let convert_str = res.to_string();
73                let convert_str = &convert_str[1..convert_str.len() - 1];
74                f.write_str(convert_str.trim())
75            }
76            Script::Other { code, .. } => f.write_str(code),
77        }
78    }
79}