neutralts/bif/
parse_bif_join.rs

1#![doc = include_str!("../../doc/bif-join.md")]
2
3use crate::{bif::constants::*, bif::Bif, bif::BifError, constants::*, Value};
4
5impl<'a> Bif<'a> {
6    /*
7        {:join; /array/separator/ :}
8        {:join; /array/separator/bool true for join keys instead values/ :}
9        <li>{:join; |array|</li><li>| :}</li>
10        {:join; /array/ / :}
11    */
12    pub(crate) fn parse_bif_join(&mut self) -> Result<(), BifError> {
13        if self.mod_filter || self.mod_negate || self.mod_scope {
14            return Err(self.bif_error(BIF_ERROR_MODIFIER_NOT_ALLOWED));
15        }
16
17        self.params = self.src.clone();
18        let args = self.extract_args();
19        let mut array_name = args
20            .get(1)
21            .cloned()
22            .ok_or_else(|| self.bif_error(BIF_ERROR_ARGS_ARRAY_NOT_FOUND))?;
23        let separator = args
24            .get(2)
25            .cloned()
26            .ok_or_else(|| self.bif_error(BIF_ERROR_ARGS_SEPARATOR_NOT_FOUND))?;
27
28        // optional use keys
29        let use_keys = args.get(3).cloned().unwrap_or("".to_string());
30
31        let keys: bool = match use_keys.as_str() {
32            "" => false,
33            "false" => false,
34            "0" => false,
35            _ => true,
36        };
37
38        let data_storage;
39        array_name = format!("{}{}", "/", array_name);
40        array_name = array_name.replace(BIF_ARRAY, "/");
41        if array_name.starts_with("/local::") {
42            array_name = array_name.replace("/local::", "/");
43            data_storage = &self.shared.schema["__indir"][&self.inherit.indir]["data"];
44        } else {
45            data_storage = &self.shared.schema["data"];
46        }
47
48        let mut joined = String::new();
49        if let Some(data_value) = data_storage.pointer(&array_name) {
50            match data_value.to_owned() {
51                Value::Object(obj) => {
52                    if keys {
53                        joined = obj
54                            .keys()
55                            .map(|k| k.to_string()) // Convertir cada clave a String
56                            .collect::<Vec<String>>()
57                            .join(&separator);
58                    } else {
59                        joined = obj
60                            .values()
61                            .map(|v| match v {
62                                Value::Object(_) => "".to_string(),
63                                Value::Array(_) => "".to_string(),
64                                Value::String(s) => s.to_string(),
65                                Value::Number(n) => n.to_string(),
66                                Value::Bool(b) => b.to_string(),
67                                _ => v.to_string(),
68                            })
69                            .collect::<Vec<String>>()
70                            .join(&separator);
71                    }
72                }
73                Value::Array(arr) => {
74                    if keys {
75                        joined = (0..arr.len())
76                            .map(|i| i.to_string())
77                            .collect::<Vec<String>>()
78                            .join(&separator);
79                    } else {
80                        joined = arr
81                            .iter()
82                            .map(|v| v.as_str().unwrap_or(""))
83                            .collect::<Vec<&str>>()
84                            .join(&separator);
85                    }
86                }
87                _ => {}
88            }
89        }
90
91        self.out = joined.to_string();
92        Ok(())
93    }
94}
95
96#[cfg(test)]
97#[path = "parse_bif_join_tests.rs"]
98mod tests;