godot_core/builtin/string/
mod.rs

1/*
2 * Copyright (c) godot-rust; Bromeon and contributors.
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 */
7
8//! Godot-types that are Strings.
9
10mod gstring;
11mod macros;
12mod node_path;
13mod string_macros;
14mod string_name;
15
16pub use gstring::*;
17pub use node_path::NodePath;
18pub use string_name::*;
19
20use crate::meta;
21use crate::meta::error::ConvertError;
22use crate::meta::{FromGodot, GodotConvert, ToGodot};
23
24impl GodotConvert for &str {
25    type Via = GString;
26}
27
28impl ToGodot for &str {
29    type Pass = meta::ByValue;
30
31    fn to_godot(&self) -> Self::Via {
32        GString::from(*self)
33    }
34}
35
36impl GodotConvert for String {
37    type Via = GString;
38}
39
40impl ToGodot for String {
41    type Pass = meta::ByValue;
42
43    fn to_godot(&self) -> Self::Via {
44        GString::from(self)
45    }
46}
47
48impl FromGodot for String {
49    fn try_from_godot(via: Self::Via) -> Result<Self, ConvertError> {
50        Ok(via.to_string())
51    }
52}
53
54// ----------------------------------------------------------------------------------------------------------------------------------------------
55// Encoding
56
57/// Specifies string encoding.
58///
59/// Used in functions such as [`GString::try_from_bytes()`][GString::try_from_bytes] to handle multiple input string encodings.
60#[non_exhaustive]
61#[derive(Copy, Clone, Eq, PartialEq, Debug)]
62pub enum Encoding {
63    Ascii,
64    Latin1,
65    Utf8,
66}
67
68// ----------------------------------------------------------------------------------------------------------------------------------------------
69// Utilities
70
71fn populated_or_none(s: GString) -> Option<GString> {
72    if s.is_empty() {
73        None
74    } else {
75        Some(s)
76    }
77}
78
79// ----------------------------------------------------------------------------------------------------------------------------------------------
80// Padding, alignment and precision support
81
82// Used by sub-modules of this module.
83use standard_fmt::pad_if_needed;
84
85mod standard_fmt {
86    use std::fmt;
87    use std::fmt::Write;
88
89    pub fn pad_if_needed<F>(f: &mut fmt::Formatter<'_>, display_impl: F) -> fmt::Result
90    where
91        F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
92    {
93        let needs_format = f.width().is_some() || f.precision().is_some() || f.align().is_some();
94
95        // Early exit if no custom formatting is needed.
96        if !needs_format {
97            return display_impl(f);
98        }
99
100        let ic = FmtInterceptor { display_impl };
101
102        let mut local_str = String::new();
103        write!(&mut local_str, "{ic}")?;
104        f.pad(&local_str)
105    }
106
107    struct FmtInterceptor<F>
108    where
109        F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
110    {
111        display_impl: F,
112    }
113
114    impl<F> fmt::Display for FmtInterceptor<F>
115    where
116        F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
117    {
118        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119            (self.display_impl)(f)
120        }
121    }
122}