Skip to main content

godot_core/builtin/strings/
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::{ExFind as GStringExFind, ExSplit as GStringExSplit, *};
17pub use node_path::NodePath;
18pub use string_name::{ExFind as StringNameExFind, ExSplit as StringNameExSplit, *};
19
20use crate::meta;
21use crate::meta::error::ConvertError;
22use crate::meta::shape::GodotShape;
23use crate::meta::{FromGodot, GodotConvert, ToGodot};
24
25impl GodotConvert for &str {
26    type Via = GString;
27
28    fn godot_shape() -> GodotShape {
29        GString::godot_shape()
30    }
31}
32
33impl ToGodot for &str {
34    type Pass = meta::ByValue;
35
36    fn to_godot(&self) -> Self::Via {
37        GString::from(*self)
38    }
39}
40
41impl GodotConvert for String {
42    type Via = GString;
43
44    fn godot_shape() -> GodotShape {
45        GString::godot_shape()
46    }
47}
48
49impl ToGodot for String {
50    type Pass = meta::ByValue;
51
52    fn to_godot(&self) -> Self::Via {
53        GString::from(self)
54    }
55}
56
57impl FromGodot for String {
58    fn try_from_godot(via: Self::Via) -> Result<Self, ConvertError> {
59        Ok(via.to_string())
60    }
61}
62
63// ----------------------------------------------------------------------------------------------------------------------------------------------
64// Encoding
65
66/// Specifies string encoding.
67///
68/// Used in functions such as [`GString::try_from_bytes()`][GString::try_from_bytes] to handle multiple input string encodings.
69#[non_exhaustive]
70#[derive(Copy, Clone, Eq, PartialEq, Debug)]
71pub enum Encoding {
72    Ascii,
73    Latin1,
74    Utf8,
75}
76
77// ----------------------------------------------------------------------------------------------------------------------------------------------
78// Utilities
79
80fn populated_or_none(s: GString) -> Option<GString> {
81    if s.is_empty() { None } else { Some(s) }
82}
83
84// ----------------------------------------------------------------------------------------------------------------------------------------------
85// Padding, alignment and precision support
86
87// Used by sub-modules of this module.
88use standard_fmt::pad_if_needed;
89
90mod standard_fmt {
91    use std::fmt;
92    use std::fmt::Write;
93
94    pub fn pad_if_needed<F>(f: &mut fmt::Formatter<'_>, display_impl: F) -> fmt::Result
95    where
96        F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
97    {
98        let needs_format = f.width().is_some() || f.precision().is_some() || f.align().is_some();
99
100        // Early exit if no custom formatting is needed.
101        if !needs_format {
102            return display_impl(f);
103        }
104
105        let ic = FmtInterceptor { display_impl };
106
107        let mut local_str = String::new();
108        write!(&mut local_str, "{ic}")?;
109        f.pad(&local_str)
110    }
111
112    struct FmtInterceptor<F>
113    where
114        F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
115    {
116        display_impl: F,
117    }
118
119    impl<F> fmt::Display for FmtInterceptor<F>
120    where
121        F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
122    {
123        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124            (self.display_impl)(f)
125        }
126    }
127}