qt_build_utils/qml/
qmluri.rs

1// SPDX-FileCopyrightText: 2025 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
2// SPDX-FileContributor: Andrew Hayzen <andrew.hayzen@kdab.com>
3//
4// SPDX-License-Identifier: MIT OR Apache-2.0
5
6use std::fmt::Display;
7
8/// A builder for representing a QML uri
9#[derive(PartialEq, Eq, Clone)]
10pub struct QmlUri {
11    uri: Vec<String>,
12}
13
14impl From<&str> for QmlUri {
15    fn from(value: &str) -> Self {
16        Self::new(value.split('.'))
17    }
18}
19
20impl From<&QmlUri> for QmlUri {
21    fn from(value: &QmlUri) -> Self {
22        value.clone()
23    }
24}
25
26impl Display for QmlUri {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        f.write_str(&self.as_dots())
29    }
30}
31
32impl QmlUri {
33    /// Construct a [QmlUri] from a given string
34    ///
35    /// If the uri segments are not alphanumeric this will panic
36    pub fn new(uri: impl IntoIterator<Item = impl Into<String>>) -> Self {
37        let uri: Vec<_> = uri.into_iter().map(Into::into).collect();
38
39        // Only allow alphanumeric uri parts for now
40        if uri.iter().any(|part| {
41            part.chars()
42                .any(|c| !(c.is_ascii_alphanumeric() || c == '_'))
43        }) {
44            panic!("QML uri parts must be alphanumeric: {uri:?}");
45        }
46
47        Self { uri }
48    }
49
50    /// Retrieve the QML uri in directory form
51    pub fn as_dirs(&self) -> String {
52        self.uri.join("/")
53    }
54
55    /// Retrieve the QML uri in dot form
56    pub fn as_dots(&self) -> String {
57        self.uri.join(".")
58    }
59
60    /// Retrieve the QML uri in underscore form
61    pub fn as_underscores(&self) -> String {
62        self.uri.join("_")
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use super::*;
69
70    #[test]
71    fn uri() {
72        assert_eq!(QmlUri::from("a.b.c").uri, ["a", "b", "c"]);
73        assert_eq!(QmlUri::new(["a", "b", "c"]).uri, ["a", "b", "c"]);
74    }
75
76    #[test]
77    #[should_panic]
78    fn uri_invalid() {
79        QmlUri::new(["a,b"]);
80    }
81
82    #[test]
83    fn as_n() {
84        let uri = QmlUri::new(["a", "b", "c_d"]);
85        assert_eq!(uri.as_dirs(), "a/b/c_d");
86        assert_eq!(uri.as_dots(), "a.b.c_d");
87        assert_eq!(uri.as_underscores(), "a_b_c_d");
88    }
89}