1#![deny(warnings, unused_variables, missing_docs, unsafe_code, unused_extern_crates)]
2#![cfg_attr(feature = "unstable", feature(test))]
3
4#[cfg(feature = "heavyweight")]
16extern crate regex;
17
18#[cfg(feature = "heavyweight")]
19#[macro_use] extern crate lazy_static;
20
21pub mod cases;
32pub mod numbers;
36pub mod suffix;
39#[cfg(feature = "heavyweight")]
45pub mod string;
46
47
48#[cfg(feature = "heavyweight")]
49use cases::classcase::to_class_case;
50#[cfg(feature = "heavyweight")]
51use cases::classcase::is_class_case;
52
53use cases::camelcase::to_camel_case;
54use cases::camelcase::is_camel_case;
55
56use cases::pascalcase::to_pascal_case;
57use cases::pascalcase::is_pascal_case;
58
59use cases::snakecase::to_snake_case;
60use cases::snakecase::is_snake_case;
61
62use cases::screamingsnakecase::to_screaming_snake_case;
63use cases::screamingsnakecase::is_screaming_snake_case;
64
65use cases::kebabcase::to_kebab_case;
66use cases::kebabcase::is_kebab_case;
67
68use cases::traincase::to_train_case;
69use cases::traincase::is_train_case;
70
71use cases::sentencecase::to_sentence_case;
72use cases::sentencecase::is_sentence_case;
73
74use cases::titlecase::to_title_case;
75use cases::titlecase::is_title_case;
76
77#[cfg(feature = "heavyweight")]
78use cases::tablecase::to_table_case;
79#[cfg(feature = "heavyweight")]
80use cases::tablecase::is_table_case;
81
82use numbers::ordinalize::ordinalize;
83use numbers::deordinalize::deordinalize;
84
85use suffix::foreignkey::to_foreign_key;
86use suffix::foreignkey::is_foreign_key;
87
88#[cfg(feature = "heavyweight")]
89use string::demodulize::demodulize;
90#[cfg(feature = "heavyweight")]
91use string::deconstantize::deconstantize;
92
93#[cfg(feature = "heavyweight")]
94use string::pluralize::to_plural;
95#[cfg(feature = "heavyweight")]
96use string::singularize::to_singular;
97
98#[allow(missing_docs)]
99pub trait Inflector {
100
101 fn to_camel_case(&self) -> String;
102 fn is_camel_case(&self) -> bool;
103
104 fn to_pascal_case(&self) -> String;
105 fn is_pascal_case(&self) -> bool;
106
107 fn to_snake_case(&self) -> String;
108 fn is_snake_case(&self) -> bool;
109
110 fn to_screaming_snake_case(&self) -> String;
111 fn is_screaming_snake_case(&self) -> bool;
112
113 fn to_kebab_case(&self) -> String;
114 fn is_kebab_case(&self) -> bool;
115
116 fn to_train_case(&self) -> String;
117 fn is_train_case(&self) -> bool;
118
119 fn to_sentence_case(&self) -> String;
120 fn is_sentence_case(&self) -> bool;
121
122 fn to_title_case(&self) -> String;
123 fn is_title_case(&self) -> bool;
124
125 fn ordinalize(&self) -> String;
126 fn deordinalize(&self) -> String;
127
128 fn to_foreign_key(&self) -> String;
129 fn is_foreign_key(&self) -> bool;
130
131 #[cfg(feature = "heavyweight")]
132 fn demodulize(&self) -> String;
133 #[cfg(feature = "heavyweight")]
134 fn deconstantize(&self) -> String;
135
136 #[cfg(feature = "heavyweight")]
137 fn to_class_case(&self) -> String;
138 #[cfg(feature = "heavyweight")]
139 fn is_class_case(&self) -> bool;
140
141 #[cfg(feature = "heavyweight")]
142 fn to_table_case(&self) -> String;
143 #[cfg(feature = "heavyweight")]
144 fn is_table_case(&self) -> bool;
145 #[cfg(feature = "heavyweight")]
146 fn to_plural(&self) -> String;
147 #[cfg(feature = "heavyweight")]
148 fn to_singular(&self) -> String;
149}
150
151
152#[allow(missing_docs)]
153pub trait InflectorNumbers {
154 fn ordinalize(&self) -> String;
155}
156
157
158macro_rules! define_implementations {
159 ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => {
160 $(
161 #[inline]
162 fn $imp_trait(&$slf) -> $typ {
163 $imp_trait($slf)
164 }
165 )*
166 }
167}
168
169macro_rules! define_number_implementations {
170 ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => {
171 $(
172 #[inline]
173 fn $imp_trait(&$slf) -> $typ {
174 $imp_trait(&$slf.to_string())
175 }
176 )*
177 }
178}
179
180macro_rules! define_gated_implementations {
181 ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => {
182 $(
183 #[inline]
184 #[cfg(feature = "heavyweight")]
185 fn $imp_trait(&$slf) -> $typ {
186 $imp_trait($slf)
187 }
188 )*
189 }
190}
191
192macro_rules! implement_string_for {
193 ( $trt:ident; $($typ:ident), *) => {
194 $(
195 impl $trt for $typ {
196 define_implementations![self;
197 to_camel_case => String,
198 is_camel_case => bool,
199 to_pascal_case => String,
200 is_pascal_case => bool,
201 to_screaming_snake_case => String,
202 is_screaming_snake_case => bool,
203 to_snake_case => String,
204 is_snake_case => bool,
205 to_kebab_case => String,
206 is_kebab_case => bool,
207 to_train_case => String,
208 is_train_case => bool,
209 to_sentence_case => String,
210 is_sentence_case => bool,
211 to_title_case => String,
212 is_title_case => bool,
213 to_foreign_key => String,
214 is_foreign_key => bool,
215 ordinalize => String,
216 deordinalize => String
217 ];
218 define_gated_implementations![self;
219 to_class_case => String,
220 is_class_case => bool,
221 to_table_case => String,
222 is_table_case => bool,
223 to_plural => String,
224 to_singular => String,
225 demodulize => String,
226 deconstantize => String
227 ];
228 }
229 )*
230 }
231}
232
233macro_rules! implement_number_for {
234 ( $trt:ident; $($typ:ident), *) => {
235 $(
236 impl $trt for $typ {
237 define_number_implementations![self;
238 ordinalize => String
239 ];
240 }
241 )*
242 }
243}
244
245implement_string_for![
246 Inflector;
247 String, str
248];
249
250implement_number_for![
251 InflectorNumbers;
252 i8, i16, i32, i64, u8, u16, u32, u64, isize, usize, f32, f64
253];
254
255#[cfg(all(feature = "unstable", test))]
256mod benchmarks {
257 extern crate test;
258 use self::test::Bencher;
259 use ::Inflector;
260
261 macro_rules! benchmarks {
262 ( $($test_name:ident => $imp_trait:ident => $to_cast:expr), *) => {
263 $(
264 #[bench]
265 fn $test_name(b: &mut Bencher) {
266 b.iter(|| {
267 $to_cast.$imp_trait()
268 });
269 }
270 )*
271 }
272 }
273
274 benchmarks![
275 benchmark_str_to_camel => to_camel_case => "foo_bar",
276 benchmark_str_is_camel => is_camel_case => "fooBar",
277 benchmark_str_to_screaming_snake => to_screaming_snake_case => "fooBar",
278 benchmark_str_is_screaming_snake => is_screaming_snake_case => "FOO_BAR",
279 benchmark_str_to_snake => to_snake_case => "fooBar",
280 benchmark_str_is_snake => is_snake_case => "foo_bar",
281 benchmark_str_to_kebab => to_kebab_case => "fooBar",
282 benchmark_str_is_kebab => is_kebab_case => "foo-bar",
283 benchmark_str_to_train => to_train_case => "fooBar",
284 benchmark_str_is_train => is_train_case => "Foo-Bar",
285 benchmark_str_to_sentence => to_sentence_case => "fooBar",
286 benchmark_str_is_sentence => is_sentence_case => "Foo bar",
287 benchmark_str_to_title => to_title_case => "fooBar",
288 benchmark_str_is_title => is_title_case => "Foo Bar",
289 benchmark_str_ordinalize => ordinalize => "1",
290 benchmark_str_deordinalize => deordinalize => "1st",
291 benchmark_str_to_foreign_key => to_foreign_key => "Foo::Bar",
292 benchmark_str_is_foreign_key => is_foreign_key => "bar_id",
293 benchmark_string_to_camel => to_camel_case => "foo_bar".to_string(),
294 benchmark_string_is_camel => is_camel_case => "fooBar".to_string(),
295 benchmark_string_to_screaming_snake => to_screaming_snake_case => "fooBar".to_string(),
296 benchmark_string_is_screaming_snake => is_screaming_snake_case => "FOO_BAR".to_string(),
297 benchmark_string_to_snake => to_snake_case => "fooBar".to_string(),
298 benchmark_string_is_snake => is_snake_case => "foo_bar".to_string(),
299 benchmark_string_to_kebab => to_kebab_case => "fooBar".to_string(),
300 benchmark_string_is_kebab => is_kebab_case => "foo-bar".to_string(),
301 benchmark_string_to_train => to_train_case => "fooBar".to_string(),
302 benchmark_string_is_train => is_train_case => "Foo-Bar".to_string(),
303 benchmark_string_to_sentence => to_sentence_case => "fooBar".to_string(),
304 benchmark_string_is_sentence => is_sentence_case => "Foo bar".to_string(),
305 benchmark_string_to_title => to_title_case => "fooBar".to_string(),
306 benchmark_string_is_title => is_title_case => "Foo Bar".to_string(),
307 benchmark_string_ordinalize => ordinalize => "1".to_string(),
308 benchmark_string_deordinalize => deordinalize => "1st".to_string(),
309 benchmark_string_to_foreign_key => to_foreign_key => "Foo::Bar".to_string(),
310 benchmark_string_is_foreign_key => is_foreign_key => "bar_id".to_string()
311 ];
312
313 #[cfg(feature = "heavyweight")]
314 benchmarks![
315 benchmark_str_to_class => to_class_case => "foo",
316 benchmark_str_is_class => is_class_case => "Foo",
317 benchmark_str_to_table => to_table_case => "fooBar",
318 benchmark_str_is_table => is_table_case => "foo_bars",
319 benchmark_str_pluralize => to_plural => "crate",
320 benchmark_str_singular => to_singular => "crates",
321 benchmark_string_to_class => to_class_case => "foo".to_string(),
322 benchmark_string_is_class => is_class_case => "Foo".to_string(),
323 benchmark_string_to_table => to_table_case => "fooBar".to_string(),
324 benchmark_string_is_table => is_table_case => "foo_bars".to_string(),
325 benchmark_string_pluralize => to_plural => "crate".to_string(),
326 benchmark_string_singular => to_singular => "crates".to_string(),
327 benchmark_string_demodulize => demodulize => "Foo::Bar".to_string(),
328 benchmark_string_deconstantize => deconstantize => "Foo::Bar".to_string(),
329 benchmark_str_demodulize => demodulize => "Foo::Bar",
330 benchmark_str_deconstantize => deconstantize => "Foo::Bar"
331 ];
332}