1
+ use crate :: persistent_list_map:: PersistentListMap ;
2
+ use crate :: traits;
1
3
use std:: fmt;
2
4
use std:: hash:: Hash ;
3
5
6
+ use crate :: meta;
7
+
4
8
#[ derive( Hash , PartialEq , Eq , Clone , Debug ) ]
5
9
pub struct Symbol {
6
10
pub name : String ,
@@ -11,6 +15,12 @@ pub struct Symbol {
11
15
// route, the sort of invariants ADTs are good at.
12
16
// Most likely, we will reimplement this as Option<String>
13
17
pub ns : String ,
18
+ pub meta : PersistentListMap ,
19
+ }
20
+ macro_rules! sym {
21
+ ( $x: expr) => {
22
+ Symbol :: intern( $x)
23
+ }
14
24
}
15
25
impl Symbol {
16
26
pub fn intern ( name : & str ) -> Symbol {
@@ -37,6 +47,7 @@ impl Symbol {
37
47
Symbol {
38
48
name : String :: from ( name) ,
39
49
ns : String :: from ( ns) ,
50
+ meta : PersistentListMap :: Empty ,
40
51
}
41
52
}
42
53
pub fn unqualified ( & self ) -> Symbol {
@@ -47,6 +58,26 @@ impl Symbol {
47
58
}
48
59
pub fn name ( & self ) -> & str {
49
60
& self . name
61
+ // @TODO use IPersistentMap instead perhaps
62
+ pub fn meta ( & self ) -> PersistentListMap {
63
+ self . meta . clone ( )
64
+ }
65
+ pub fn with_meta ( & self , meta : PersistentListMap ) -> Symbol {
66
+ Symbol {
67
+ name : self . name . clone ( ) , // String::from(self.name.clone()),
68
+ ns : self . ns . clone ( ) , // String::from(self.ns.clone()),
69
+ meta,
70
+ }
71
+ }
72
+ }
73
+ impl traits:: IMeta for Symbol {
74
+ fn meta ( & self ) -> PersistentListMap {
75
+ self . meta ( )
76
+ }
77
+ }
78
+ impl traits:: IObj for Symbol {
79
+ fn with_meta ( & self , meta : PersistentListMap ) -> Symbol {
80
+ self . with_meta ( meta)
50
81
}
51
82
}
52
83
impl fmt:: Display for Symbol {
@@ -61,7 +92,14 @@ impl fmt::Display for Symbol {
61
92
mod tests {
62
93
63
94
mod symbol_tests {
95
+ use crate :: keyword:: Keyword ;
96
+ use crate :: maps:: MapEntry ;
97
+ use crate :: meta;
98
+ use crate :: persistent_list_map:: ToPersistentListMapIter ;
99
+ use crate :: persistent_list_map:: { PersistentListMap , PersistentListMapIter } ;
64
100
use crate :: symbol:: Symbol ;
101
+ use crate :: value:: ToValue ;
102
+ use crate :: value:: Value ;
65
103
use std:: collections:: HashMap ;
66
104
67
105
#[ test]
@@ -70,7 +108,8 @@ mod tests {
70
108
Symbol :: intern( "a" ) ,
71
109
Symbol {
72
110
ns: String :: from( "" ) ,
73
- name: String :: from( "a" )
111
+ name: String :: from( "a" ) ,
112
+ meta: PersistentListMap :: Empty ,
74
113
}
75
114
) ;
76
115
}
@@ -81,45 +120,87 @@ mod tests {
81
120
Symbol :: intern_with_ns( "clojure.core" , "a" ) ,
82
121
Symbol {
83
122
ns: String :: from( "clojure.core" ) ,
84
- name: String :: from( "a" )
123
+ name: String :: from( "a" ) ,
124
+ meta: PersistentListMap :: Empty
85
125
}
86
126
) ;
87
127
assert_eq ! (
88
128
Symbol :: intern_with_ns( "" , "a" ) ,
89
129
Symbol {
90
130
ns: String :: from( "" ) ,
91
- name: String :: from( "a" )
131
+ name: String :: from( "a" ) ,
132
+ meta: PersistentListMap :: Empty
92
133
}
93
134
) ;
94
135
assert_eq ! (
95
136
Symbol :: intern( "a" ) ,
96
137
Symbol {
97
138
ns: String :: from( "" ) ,
98
- name: String :: from( "a" )
139
+ name: String :: from( "a" ) ,
140
+ meta: PersistentListMap :: Empty
99
141
}
100
142
) ;
101
143
assert_eq ! (
102
144
Symbol :: intern( "clojure.core/a" ) ,
103
145
Symbol {
104
146
ns: String :: from( "clojure.core" ) ,
105
- name: String :: from( "a" )
147
+ name: String :: from( "a" ) ,
148
+ meta: PersistentListMap :: Empty
106
149
}
107
150
) ;
108
151
assert_eq ! (
109
152
Symbol :: intern( "clojure/a" ) ,
110
153
Symbol {
111
154
ns: String :: from( "clojure" ) ,
112
- name: String :: from( "a" )
155
+ name: String :: from( "a" ) ,
156
+ meta: PersistentListMap :: Empty ,
113
157
}
114
158
) ;
115
159
assert_eq ! (
116
160
Symbol :: intern( "/a" ) ,
117
161
Symbol {
118
162
ns: String :: from( "" ) ,
119
- name: String :: from( "a" )
163
+ name: String :: from( "a" ) ,
164
+ meta: PersistentListMap :: Empty ,
120
165
}
121
166
) ;
122
167
}
168
+ #[ test]
169
+ fn test_with_meta ( ) {
170
+ assert_eq ! (
171
+ Symbol :: intern_with_ns(
172
+ "namespace" ,
173
+ "name"
174
+ ) . with_meta(
175
+ persistent_list_map!( map_entry!( "key" , "value" ) )
176
+ ) ,
177
+ Symbol {
178
+ ns: String :: from( "namespace" ) ,
179
+ name: String :: from( "name" ) ,
180
+ meta: persistent_list_map!( map_entry!( "key" , "value" ) )
181
+ }
182
+ ) ;
183
+ assert_eq ! (
184
+ Symbol :: intern_with_ns(
185
+ "namespace" ,
186
+ "name"
187
+ ) . with_meta(
188
+ merge!(
189
+ PersistentListMap :: Empty ,
190
+ map_entry!( "key" , "value" )
191
+ )
192
+ ) ,
193
+ Symbol {
194
+ ns: String :: from( "namespace" ) ,
195
+ name: String :: from( "name" ) ,
196
+ meta: merge!(
197
+ PersistentListMap :: Empty ,
198
+ map_entry!( "key" , "value" )
199
+ )
200
+ }
201
+ ) ;
202
+ }
203
+
123
204
#[ test]
124
205
fn test_work_with_hashmap ( ) {
125
206
let mut hashmap = HashMap :: new ( ) ;
0 commit comments