5
5
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
6
*/
7
7
8
- use std:: fmt;
8
+ use std:: {
9
+ fmt,
10
+ ops:: {
11
+ Bound :: { Excluded , Included , Unbounded } ,
12
+ RangeBounds ,
13
+ } ,
14
+ } ;
9
15
10
16
use godot_ffi as sys;
11
17
use godot_ffi:: { ffi_methods, GodotFfi } ;
@@ -41,8 +47,33 @@ impl NodePath {
41
47
Self { opaque }
42
48
}
43
49
44
- pub fn is_empty ( & self ) -> bool {
45
- self . as_inner ( ) . is_empty ( )
50
+ /// Returns the number of node names in the path. Property subnames are not included.
51
+ pub fn get_name_count ( & self ) -> u32 {
52
+ self . as_inner ( )
53
+ . get_name_count ( )
54
+ . try_into ( )
55
+ . expect ( "Godot name counts are non negative int" )
56
+ }
57
+
58
+ /// Returns the node name indicated by `idx`, starting from 0. If `idx` is out of bounds, [`None`] is returned.
59
+ /// See also [`NodePath::get_subname_count`] and [`NodePath::get_name_count`].
60
+ pub fn get_name ( & self , idx : u32 ) -> Option < StringName > {
61
+ let inner = self . as_inner ( ) ;
62
+ let idx = idx as i64 ;
63
+ // This check checks both data being empty (get_name_count returns 0) and index out of bounds.
64
+ if idx >= inner. get_name_count ( ) {
65
+ None
66
+ } else {
67
+ Some ( inner. get_name ( idx) )
68
+ }
69
+ }
70
+
71
+ /// Returns the number of property names ("subnames") in the path. Each subname in the node path is listed after a colon character (`:`).
72
+ pub fn get_subname_count ( & self ) -> u32 {
73
+ self . as_inner ( )
74
+ . get_subname_count ( )
75
+ . try_into ( )
76
+ . expect ( "Godot subname counts are non negative int" )
46
77
}
47
78
48
79
/// Returns a 32-bit integer hash value representing the string.
@@ -53,6 +84,50 @@ impl NodePath {
53
84
. expect ( "Godot hashes are uint32_t" )
54
85
}
55
86
87
+ /// Returns the property name indicated by `idx`, starting from 0. If `idx` is out of bounds, [`None`] is returned.
88
+ /// See also [`NodePath::get_subname_count`].
89
+ pub fn get_subname ( & self , idx : u32 ) -> Option < StringName > {
90
+ let inner = self . as_inner ( ) ;
91
+ let idx = idx as i64 ;
92
+ // This check checks both data being empty (get_subname_count returns 0) and index out of bounds.
93
+ if idx >= inner. get_subname_count ( ) {
94
+ None
95
+ } else {
96
+ Some ( inner. get_subname ( idx) )
97
+ }
98
+ }
99
+
100
+ /// Returns the slice of the [`NodePath`] as a new [`NodePath`]
101
+ pub fn slice ( & self , range : impl RangeBounds < i64 > ) -> NodePath {
102
+ self . as_inner ( ) . slice (
103
+ match range. start_bound ( ) {
104
+ Excluded ( & start) => {
105
+ if start == -1 {
106
+ // Default end from godot, since the start is excluded.
107
+ i32:: MAX as i64
108
+ } else {
109
+ start + 1
110
+ }
111
+ }
112
+ Included ( & start) => start,
113
+ Unbounded => 0 ,
114
+ } ,
115
+ match range. end_bound ( ) {
116
+ Excluded ( & end) => end,
117
+ Included ( & end) => {
118
+ if end == -1 {
119
+ // Default end from godot, since the end is excluded.
120
+ i32:: MAX as i64
121
+ } else {
122
+ end + 1
123
+ }
124
+ }
125
+ // Default end from godot.
126
+ Unbounded => i32:: MAX as i64 ,
127
+ } ,
128
+ )
129
+ }
130
+
56
131
crate :: meta:: declare_arg_method! {
57
132
/// Use as argument for an [`impl AsArg<GString|StringName>`][crate::meta::AsArg] parameter.
58
133
///
0 commit comments