1+ use crate :: persistent_list_map:: PersistentListMap ;
2+ use crate :: traits;
13use std:: fmt;
24use std:: hash:: Hash ;
35
6+ use crate :: meta;
7+
48#[ derive( Hash , PartialEq , Eq , Clone , Debug ) ]
59pub struct Symbol {
610 pub name : String ,
@@ -11,6 +15,12 @@ pub struct Symbol {
1115 // route, the sort of invariants ADTs are good at.
1216 // Most likely, we will reimplement this as Option<String>
1317 pub ns : String ,
18+ pub meta : PersistentListMap ,
19+ }
20+ macro_rules! sym {
21+ ( $x: expr) => {
22+ Symbol :: intern( $x)
23+ }
1424}
1525impl Symbol {
1626 pub fn intern ( name : & str ) -> Symbol {
@@ -37,6 +47,7 @@ impl Symbol {
3747 Symbol {
3848 name : String :: from ( name) ,
3949 ns : String :: from ( ns) ,
50+ meta : PersistentListMap :: Empty ,
4051 }
4152 }
4253 pub fn unqualified ( & self ) -> Symbol {
@@ -47,6 +58,26 @@ impl Symbol {
4758 }
4859 pub fn name ( & self ) -> & str {
4960 & 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)
5081 }
5182}
5283impl fmt:: Display for Symbol {
@@ -61,7 +92,14 @@ impl fmt::Display for Symbol {
6192mod tests {
6293
6394 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 } ;
64100 use crate :: symbol:: Symbol ;
101+ use crate :: value:: ToValue ;
102+ use crate :: value:: Value ;
65103 use std:: collections:: HashMap ;
66104
67105 #[ test]
@@ -70,7 +108,8 @@ mod tests {
70108 Symbol :: intern( "a" ) ,
71109 Symbol {
72110 ns: String :: from( "" ) ,
73- name: String :: from( "a" )
111+ name: String :: from( "a" ) ,
112+ meta: PersistentListMap :: Empty ,
74113 }
75114 ) ;
76115 }
@@ -81,45 +120,87 @@ mod tests {
81120 Symbol :: intern_with_ns( "clojure.core" , "a" ) ,
82121 Symbol {
83122 ns: String :: from( "clojure.core" ) ,
84- name: String :: from( "a" )
123+ name: String :: from( "a" ) ,
124+ meta: PersistentListMap :: Empty
85125 }
86126 ) ;
87127 assert_eq ! (
88128 Symbol :: intern_with_ns( "" , "a" ) ,
89129 Symbol {
90130 ns: String :: from( "" ) ,
91- name: String :: from( "a" )
131+ name: String :: from( "a" ) ,
132+ meta: PersistentListMap :: Empty
92133 }
93134 ) ;
94135 assert_eq ! (
95136 Symbol :: intern( "a" ) ,
96137 Symbol {
97138 ns: String :: from( "" ) ,
98- name: String :: from( "a" )
139+ name: String :: from( "a" ) ,
140+ meta: PersistentListMap :: Empty
99141 }
100142 ) ;
101143 assert_eq ! (
102144 Symbol :: intern( "clojure.core/a" ) ,
103145 Symbol {
104146 ns: String :: from( "clojure.core" ) ,
105- name: String :: from( "a" )
147+ name: String :: from( "a" ) ,
148+ meta: PersistentListMap :: Empty
106149 }
107150 ) ;
108151 assert_eq ! (
109152 Symbol :: intern( "clojure/a" ) ,
110153 Symbol {
111154 ns: String :: from( "clojure" ) ,
112- name: String :: from( "a" )
155+ name: String :: from( "a" ) ,
156+ meta: PersistentListMap :: Empty ,
113157 }
114158 ) ;
115159 assert_eq ! (
116160 Symbol :: intern( "/a" ) ,
117161 Symbol {
118162 ns: String :: from( "" ) ,
119- name: String :: from( "a" )
163+ name: String :: from( "a" ) ,
164+ meta: PersistentListMap :: Empty ,
120165 }
121166 ) ;
122167 }
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+
123204 #[ test]
124205 fn test_work_with_hashmap ( ) {
125206 let mut hashmap = HashMap :: new ( ) ;
0 commit comments