decasify 0.6.1__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {decasify-0.6.1 → decasify-0.7.1}/Cargo.lock +1 -1
- {decasify-0.6.1 → decasify-0.7.1}/Cargo.toml +1 -1
- {decasify-0.6.1 → decasify-0.7.1}/PKG-INFO +10 -10
- {decasify-0.6.1 → decasify-0.7.1}/README.md +9 -9
- {decasify-0.6.1 → decasify-0.7.1}/src/bin/decasify.rs +12 -11
- {decasify-0.6.1 → decasify-0.7.1}/src/cli.rs +7 -7
- {decasify-0.6.1 → decasify-0.7.1}/src/content.rs +14 -12
- {decasify-0.6.1 → decasify-0.7.1}/src/lib.rs +133 -75
- {decasify-0.6.1 → decasify-0.7.1}/src/lua.rs +43 -18
- {decasify-0.6.1 → decasify-0.7.1}/src/python.rs +16 -7
- {decasify-0.6.1 → decasify-0.7.1}/src/types.rs +49 -12
- decasify-0.7.1/src/wasm.rs +33 -0
- decasify-0.6.1/fibby/bin/decasify.rs +0 -54
- decasify-0.6.1/fibby/lib/luarocks/rocks-5.4/decasify.nvim/dev-1/bin/decasify.rs +0 -54
- decasify-0.6.1/src/wasm.rs +0 -32
- decasify-0.6.1/t/debug/build/unicode_titlecase-16618a8ffa363649/out/casing.rs +0 -1481
- decasify-0.6.1/t/release/build/unicode_titlecase-b9387febdd3ed11b/out/casing.rs +0 -1481
- {decasify-0.6.1 → decasify-0.7.1}/build-aux/build.rs +0 -0
- {decasify-0.6.1 → decasify-0.7.1}/pyproject.toml +0 -0
- {decasify-0.6.1 → decasify-0.7.1}/tests/cli.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: decasify
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Classifier: Development Status :: 5 - Production/Stable
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: Natural Language :: English
|
|
@@ -123,21 +123,21 @@ In your `Cargo.toml` file.
|
|
|
123
123
|
|
|
124
124
|
```toml
|
|
125
125
|
[dependencies]
|
|
126
|
-
decasify = "0.
|
|
126
|
+
decasify = "0.7"
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
Then use the crate functions and types in your project something like this:
|
|
130
130
|
|
|
131
131
|
```rust
|
|
132
132
|
use decasify::to_titlecase;
|
|
133
|
-
use decasify::{
|
|
133
|
+
use decasify::{Locale, StyleGuide};
|
|
134
134
|
|
|
135
135
|
fn demo() {
|
|
136
136
|
let input = "ILIK SU VE İTEN RÜZGARLAR";
|
|
137
|
-
let output = to_titlecase(input,
|
|
137
|
+
let output = to_titlecase(input, Locale::TR, StyleGuide::LanguageDefault);
|
|
138
138
|
eprintln! {"{output}"};
|
|
139
139
|
let input = "title with a twist: a colon";
|
|
140
|
-
let output = to_titlecase(input,
|
|
140
|
+
let output = to_titlecase(input, Locale::EN, StyleGuide::DaringFireball);
|
|
141
141
|
eprintln! {"{output}"};
|
|
142
142
|
}
|
|
143
143
|
```
|
|
@@ -181,10 +181,10 @@ Then import and use the provided functions and type classes:
|
|
|
181
181
|
from decasify import *
|
|
182
182
|
|
|
183
183
|
input = "ILIK SU VE İTEN RÜZGARLAR"
|
|
184
|
-
output = titlecase(input,
|
|
184
|
+
output = titlecase(input, Locale.TR)
|
|
185
185
|
print(output)
|
|
186
186
|
input = "title with a twist: a colon"
|
|
187
|
-
output = titlecase(input,
|
|
187
|
+
output = titlecase(input, Locale.EN, StyleGuide.DaringFireball)
|
|
188
188
|
print(output)
|
|
189
189
|
```
|
|
190
190
|
|
|
@@ -195,14 +195,14 @@ Depend on the WASM based JavaScript module in your project with `npm add decasif
|
|
|
195
195
|
Then import and use the provided functions and classes:
|
|
196
196
|
|
|
197
197
|
```javascript
|
|
198
|
-
import { titlecase, uppercase, lowercase,
|
|
198
|
+
import { titlecase, uppercase, lowercase, Locale, StyleGuide } from 'decasify';
|
|
199
199
|
|
|
200
200
|
var input = "ILIK SU VE İTEN RÜZGARLAR"
|
|
201
|
-
var output = titlecase(input,
|
|
201
|
+
var output = titlecase(input, Locale.TR)
|
|
202
202
|
console.log(output)
|
|
203
203
|
|
|
204
204
|
var input = "title with a twist: a colon"
|
|
205
|
-
var output = titlecase(input,
|
|
205
|
+
var output = titlecase(input, Locale.EN, StyleGuide.DaringFireball)
|
|
206
206
|
console.log(output)
|
|
207
207
|
```
|
|
208
208
|
|
|
@@ -101,21 +101,21 @@ In your `Cargo.toml` file.
|
|
|
101
101
|
|
|
102
102
|
```toml
|
|
103
103
|
[dependencies]
|
|
104
|
-
decasify = "0.
|
|
104
|
+
decasify = "0.7"
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
Then use the crate functions and types in your project something like this:
|
|
108
108
|
|
|
109
109
|
```rust
|
|
110
110
|
use decasify::to_titlecase;
|
|
111
|
-
use decasify::{
|
|
111
|
+
use decasify::{Locale, StyleGuide};
|
|
112
112
|
|
|
113
113
|
fn demo() {
|
|
114
114
|
let input = "ILIK SU VE İTEN RÜZGARLAR";
|
|
115
|
-
let output = to_titlecase(input,
|
|
115
|
+
let output = to_titlecase(input, Locale::TR, StyleGuide::LanguageDefault);
|
|
116
116
|
eprintln! {"{output}"};
|
|
117
117
|
let input = "title with a twist: a colon";
|
|
118
|
-
let output = to_titlecase(input,
|
|
118
|
+
let output = to_titlecase(input, Locale::EN, StyleGuide::DaringFireball);
|
|
119
119
|
eprintln! {"{output}"};
|
|
120
120
|
}
|
|
121
121
|
```
|
|
@@ -159,10 +159,10 @@ Then import and use the provided functions and type classes:
|
|
|
159
159
|
from decasify import *
|
|
160
160
|
|
|
161
161
|
input = "ILIK SU VE İTEN RÜZGARLAR"
|
|
162
|
-
output = titlecase(input,
|
|
162
|
+
output = titlecase(input, Locale.TR)
|
|
163
163
|
print(output)
|
|
164
164
|
input = "title with a twist: a colon"
|
|
165
|
-
output = titlecase(input,
|
|
165
|
+
output = titlecase(input, Locale.EN, StyleGuide.DaringFireball)
|
|
166
166
|
print(output)
|
|
167
167
|
```
|
|
168
168
|
|
|
@@ -173,14 +173,14 @@ Depend on the WASM based JavaScript module in your project with `npm add decasif
|
|
|
173
173
|
Then import and use the provided functions and classes:
|
|
174
174
|
|
|
175
175
|
```javascript
|
|
176
|
-
import { titlecase, uppercase, lowercase,
|
|
176
|
+
import { titlecase, uppercase, lowercase, Locale, StyleGuide } from 'decasify';
|
|
177
177
|
|
|
178
178
|
var input = "ILIK SU VE İTEN RÜZGARLAR"
|
|
179
|
-
var output = titlecase(input,
|
|
179
|
+
var output = titlecase(input, Locale.TR)
|
|
180
180
|
console.log(output)
|
|
181
181
|
|
|
182
182
|
var input = "title with a twist: a colon"
|
|
183
|
-
var output = titlecase(input,
|
|
183
|
+
var output = titlecase(input, Locale.EN, StyleGuide.DaringFireball)
|
|
184
184
|
console.log(output)
|
|
185
185
|
```
|
|
186
186
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
use decasify::cli::Cli;
|
|
5
5
|
use decasify::{to_lowercase, to_sentencecase, to_titlecase, to_uppercase};
|
|
6
|
-
use decasify::{
|
|
6
|
+
use decasify::{Case, Locale, Result, StyleGuide};
|
|
7
7
|
|
|
8
8
|
use clap::CommandFactory;
|
|
9
9
|
use std::io;
|
|
@@ -13,9 +13,9 @@ fn main() -> Result<()> {
|
|
|
13
13
|
let version = option_env!("VERGEN_GIT_DESCRIBE").unwrap_or_else(|| env!("CARGO_PKG_VERSION"));
|
|
14
14
|
let app = Cli::command().version(version);
|
|
15
15
|
let matches = app.get_matches();
|
|
16
|
-
let locale = matches.get_one::<
|
|
17
|
-
let case = matches.get_one::<
|
|
18
|
-
let style = matches.get_one::<StyleGuide>("style").
|
|
16
|
+
let locale = matches.get_one::<Locale>("locale").unwrap();
|
|
17
|
+
let case = matches.get_one::<Case>("case").unwrap().to_owned();
|
|
18
|
+
let style = matches.get_one::<StyleGuide>("style").unwrap().to_owned();
|
|
19
19
|
match matches.contains_id("input") {
|
|
20
20
|
true => {
|
|
21
21
|
let input: Vec<String> = matches
|
|
@@ -38,16 +38,17 @@ fn main() -> Result<()> {
|
|
|
38
38
|
|
|
39
39
|
fn process<I: IntoIterator<Item = String>>(
|
|
40
40
|
strings: I,
|
|
41
|
-
locale:
|
|
42
|
-
case:
|
|
43
|
-
style:
|
|
41
|
+
locale: Locale,
|
|
42
|
+
case: Case,
|
|
43
|
+
style: StyleGuide,
|
|
44
44
|
) {
|
|
45
45
|
for string in strings {
|
|
46
46
|
let output = match case {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
Case::Title => to_titlecase(string, locale, style),
|
|
48
|
+
Case::Lower => to_lowercase(string, locale),
|
|
49
|
+
Case::Upper => to_uppercase(string, locale),
|
|
50
|
+
Case::Sentence => to_sentencecase(string, locale),
|
|
51
|
+
_ => unreachable!(),
|
|
51
52
|
};
|
|
52
53
|
println!("{output}")
|
|
53
54
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
3
3
|
|
|
4
4
|
#[cfg(build)]
|
|
5
|
-
use crate::{
|
|
5
|
+
use crate::{Case, Locale, StyleGuide};
|
|
6
6
|
|
|
7
7
|
use clap::{builder, Parser};
|
|
8
8
|
use strum::VariantNames;
|
|
@@ -21,16 +21,16 @@ macro_rules! clap_enum_variants {
|
|
|
21
21
|
#[clap(author, bin_name = "decasify")]
|
|
22
22
|
pub struct Cli {
|
|
23
23
|
/// Locale
|
|
24
|
-
#[clap(short, long, default_value_t, ignore_case = true, value_parser = clap_enum_variants!(
|
|
25
|
-
pub locale:
|
|
24
|
+
#[clap(short, long, default_value_t, ignore_case = true, value_parser = clap_enum_variants!(Locale))]
|
|
25
|
+
pub locale: Locale,
|
|
26
26
|
|
|
27
27
|
/// Target case
|
|
28
|
-
#[clap(short, long, default_value_t, ignore_case = true, value_parser = clap_enum_variants!(
|
|
29
|
-
pub case:
|
|
28
|
+
#[clap(short, long, default_value_t, ignore_case = true, value_parser = clap_enum_variants!(Case))]
|
|
29
|
+
pub case: Case,
|
|
30
30
|
|
|
31
31
|
/// Style Guide
|
|
32
|
-
#[clap(short, long, ignore_case = true, value_parser = clap_enum_variants!(StyleGuide))]
|
|
33
|
-
pub style:
|
|
32
|
+
#[clap(short, long, default_value_t, ignore_case = true, value_parser = clap_enum_variants!(StyleGuide))]
|
|
33
|
+
pub style: StyleGuide,
|
|
34
34
|
|
|
35
35
|
/// Input string
|
|
36
36
|
pub input: Vec<String>,
|
|
@@ -6,20 +6,22 @@ use regex::Regex;
|
|
|
6
6
|
use std::{borrow::Cow, error, fmt, fmt::Display, str::FromStr};
|
|
7
7
|
|
|
8
8
|
#[derive(Clone, Debug, PartialEq)]
|
|
9
|
+
#[non_exhaustive]
|
|
9
10
|
pub enum Segment {
|
|
10
11
|
Separator(String),
|
|
11
12
|
Word(String),
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
#[derive(Debug, Clone)]
|
|
16
|
+
#[non_exhaustive]
|
|
15
17
|
pub struct Chunk {
|
|
16
18
|
pub segments: Vec<Segment>,
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
fn split_chunk(
|
|
21
|
+
fn split_chunk(s: &str) -> Chunk {
|
|
20
22
|
let mut segments: Vec<Segment> = Vec::new();
|
|
21
23
|
let captures = Regex::new(r"(?<separator>\p{Whitespace}+)|(?<word>\P{Whitespace}+)").unwrap();
|
|
22
|
-
for capture in captures.captures_iter(
|
|
24
|
+
for capture in captures.captures_iter(s) {
|
|
23
25
|
if let Some(m) = capture.name("separator") {
|
|
24
26
|
segments.push(Segment::Separator(m.as_str().to_string()));
|
|
25
27
|
} else if let Some(m) = capture.name("word") {
|
|
@@ -30,33 +32,33 @@ fn split_chunk(src: &str) -> Chunk {
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
impl From<String> for Chunk {
|
|
33
|
-
fn from(
|
|
34
|
-
split_chunk(
|
|
35
|
+
fn from(s: String) -> Self {
|
|
36
|
+
split_chunk(s.as_ref())
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
impl From<&String> for Chunk {
|
|
39
|
-
fn from(
|
|
40
|
-
split_chunk(
|
|
41
|
+
fn from(s: &String) -> Self {
|
|
42
|
+
split_chunk(s.as_ref())
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
impl From<&str> for Chunk {
|
|
45
|
-
fn from(
|
|
46
|
-
split_chunk(
|
|
47
|
+
fn from(s: &str) -> Self {
|
|
48
|
+
split_chunk(s)
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
impl From<&Cow<'_, str>> for Chunk {
|
|
51
|
-
fn from(
|
|
52
|
-
split_chunk(
|
|
53
|
+
fn from(s: &Cow<'_, str>) -> Self {
|
|
54
|
+
split_chunk(s)
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
impl FromStr for Chunk {
|
|
57
59
|
type Err = Box<dyn error::Error>;
|
|
58
|
-
fn from_str(
|
|
59
|
-
Ok(split_chunk(
|
|
60
|
+
fn from_str(s: &str) -> Result<Self> {
|
|
61
|
+
Ok(split_chunk(s))
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
|
|
@@ -12,7 +12,7 @@ pub mod content;
|
|
|
12
12
|
pub mod types;
|
|
13
13
|
|
|
14
14
|
pub use content::{Chunk, Segment};
|
|
15
|
-
pub use types::{
|
|
15
|
+
pub use types::{Case, Locale, Result, StyleGuide};
|
|
16
16
|
|
|
17
17
|
#[cfg(feature = "cli")]
|
|
18
18
|
pub mod cli;
|
|
@@ -26,55 +26,76 @@ pub mod python;
|
|
|
26
26
|
#[cfg(feature = "wasm")]
|
|
27
27
|
pub mod wasm;
|
|
28
28
|
|
|
29
|
+
/// Convert a string to a specific case following typesetting conventions for a target locale
|
|
30
|
+
pub fn to_case(
|
|
31
|
+
chunk: impl Into<Chunk>,
|
|
32
|
+
case: impl Into<Case>,
|
|
33
|
+
locale: impl Into<Locale>,
|
|
34
|
+
style: impl Into<StyleGuide>,
|
|
35
|
+
) -> String {
|
|
36
|
+
let chunk: Chunk = chunk.into();
|
|
37
|
+
let case: Case = case.into();
|
|
38
|
+
let locale: Locale = locale.into();
|
|
39
|
+
let style: StyleGuide = style.into();
|
|
40
|
+
match case {
|
|
41
|
+
Case::Lower => to_lowercase(chunk, locale),
|
|
42
|
+
Case::Upper => to_uppercase(chunk, locale),
|
|
43
|
+
Case::Sentence => to_sentencecase(chunk, locale),
|
|
44
|
+
Case::Title => to_titlecase(chunk, locale, style),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
/// Convert a string to title case following typesetting conventions for a target locale
|
|
30
49
|
pub fn to_titlecase(
|
|
31
50
|
chunk: impl Into<Chunk>,
|
|
32
|
-
locale:
|
|
33
|
-
style:
|
|
51
|
+
locale: impl Into<Locale>,
|
|
52
|
+
style: impl Into<StyleGuide>,
|
|
34
53
|
) -> String {
|
|
35
54
|
let chunk: Chunk = chunk.into();
|
|
55
|
+
let locale: Locale = locale.into();
|
|
56
|
+
let style: StyleGuide = style.into();
|
|
36
57
|
match locale {
|
|
37
|
-
|
|
38
|
-
|
|
58
|
+
Locale::EN => to_titlecase_en(chunk, style),
|
|
59
|
+
Locale::TR => to_titlecase_tr(chunk, style),
|
|
39
60
|
}
|
|
40
61
|
}
|
|
41
62
|
|
|
42
63
|
/// Convert a string to lower case following typesetting conventions for a target locale
|
|
43
|
-
pub fn to_lowercase(chunk: impl Into<Chunk>, locale: impl Into<
|
|
64
|
+
pub fn to_lowercase(chunk: impl Into<Chunk>, locale: impl Into<Locale>) -> String {
|
|
44
65
|
let chunk: Chunk = chunk.into();
|
|
45
|
-
let locale:
|
|
66
|
+
let locale: Locale = locale.into();
|
|
46
67
|
match locale {
|
|
47
|
-
|
|
48
|
-
|
|
68
|
+
Locale::EN => to_lowercase_en(chunk),
|
|
69
|
+
Locale::TR => to_lowercase_tr(chunk),
|
|
49
70
|
}
|
|
50
71
|
}
|
|
51
72
|
|
|
52
73
|
/// Convert a string to upper case following typesetting conventions for a target locale
|
|
53
|
-
pub fn to_uppercase(chunk: impl Into<Chunk>, locale: impl Into<
|
|
74
|
+
pub fn to_uppercase(chunk: impl Into<Chunk>, locale: impl Into<Locale>) -> String {
|
|
54
75
|
let chunk: Chunk = chunk.into();
|
|
55
|
-
let locale:
|
|
76
|
+
let locale: Locale = locale.into();
|
|
56
77
|
match locale {
|
|
57
|
-
|
|
58
|
-
|
|
78
|
+
Locale::EN => to_uppercase_en(chunk),
|
|
79
|
+
Locale::TR => to_uppercase_tr(chunk),
|
|
59
80
|
}
|
|
60
81
|
}
|
|
61
82
|
|
|
62
83
|
/// Convert a string to sentence case following typesetting conventions for a target locale
|
|
63
|
-
pub fn to_sentencecase(chunk: impl Into<Chunk>, locale: impl Into<
|
|
84
|
+
pub fn to_sentencecase(chunk: impl Into<Chunk>, locale: impl Into<Locale>) -> String {
|
|
64
85
|
let chunk: Chunk = chunk.into();
|
|
65
|
-
let locale:
|
|
86
|
+
let locale: Locale = locale.into();
|
|
66
87
|
match locale {
|
|
67
|
-
|
|
68
|
-
|
|
88
|
+
Locale::EN => to_sentencecase_en(chunk),
|
|
89
|
+
Locale::TR => to_sentencecase_tr(chunk),
|
|
69
90
|
}
|
|
70
91
|
}
|
|
71
92
|
|
|
72
|
-
fn to_titlecase_en(chunk: Chunk, style:
|
|
93
|
+
fn to_titlecase_en(chunk: Chunk, style: StyleGuide) -> String {
|
|
73
94
|
match style {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
95
|
+
StyleGuide::AssociatedPress => to_titlecase_ap(chunk),
|
|
96
|
+
StyleGuide::ChicagoManualOfStyle => to_titlecase_cmos(chunk),
|
|
97
|
+
StyleGuide::DaringFireball => to_titlecase_gruber(chunk),
|
|
98
|
+
StyleGuide::LanguageDefault => to_titlecase_gruber(chunk),
|
|
78
99
|
}
|
|
79
100
|
}
|
|
80
101
|
|
|
@@ -125,10 +146,9 @@ fn to_titlecase_gruber(chunk: Chunk) -> String {
|
|
|
125
146
|
format!("{}{}{}", leading_trivia, titilized, trailing_trivia)
|
|
126
147
|
}
|
|
127
148
|
|
|
128
|
-
fn to_titlecase_tr(chunk: Chunk, style:
|
|
149
|
+
fn to_titlecase_tr(chunk: Chunk, style: StyleGuide) -> String {
|
|
129
150
|
match style {
|
|
130
|
-
|
|
131
|
-
None => {
|
|
151
|
+
StyleGuide::LanguageDefault => {
|
|
132
152
|
let mut chunk = chunk.clone();
|
|
133
153
|
let mut done_first = false;
|
|
134
154
|
chunk.segments.iter_mut().for_each(|segment| {
|
|
@@ -146,6 +166,7 @@ fn to_titlecase_tr(chunk: Chunk, style: Option<StyleGuide>) -> String {
|
|
|
146
166
|
});
|
|
147
167
|
chunk.to_string()
|
|
148
168
|
}
|
|
169
|
+
_ => todo!("Turkish implementation doesn't support different style guides."),
|
|
149
170
|
}
|
|
150
171
|
}
|
|
151
172
|
|
|
@@ -244,6 +265,52 @@ fn to_sentencecase_tr(chunk: Chunk) -> String {
|
|
|
244
265
|
mod tests {
|
|
245
266
|
use super::*;
|
|
246
267
|
|
|
268
|
+
#[test]
|
|
269
|
+
fn cast_from_str() {
|
|
270
|
+
let res = to_titlecase("FIST", "en", "gruber");
|
|
271
|
+
assert_eq!(res, "Fist");
|
|
272
|
+
let res = to_titlecase("FIST", "tr", "");
|
|
273
|
+
assert_eq!(res, "Fıst");
|
|
274
|
+
let res = to_titlecase("FIST", "tr", "default");
|
|
275
|
+
assert_eq!(res, "Fıst");
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
#[test]
|
|
279
|
+
fn cast_from_legacy_option() {
|
|
280
|
+
let res = to_titlecase("FIST", "en", Some(StyleGuide::DaringFireball));
|
|
281
|
+
assert_eq!(res, "Fist");
|
|
282
|
+
let res = to_titlecase("FIST", "en", None);
|
|
283
|
+
assert_eq!(res, "Fist");
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
macro_rules! case {
|
|
287
|
+
($name:ident, $case:expr, $locale:expr, $style:expr, $input:expr, $expected:expr) => {
|
|
288
|
+
#[test]
|
|
289
|
+
fn $name() {
|
|
290
|
+
let actual = to_case($input, $case, $locale, $style);
|
|
291
|
+
assert_eq!(actual, $expected);
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
case!(
|
|
297
|
+
abc_title_me,
|
|
298
|
+
Case::Title,
|
|
299
|
+
Locale::EN,
|
|
300
|
+
StyleGuide::LanguageDefault,
|
|
301
|
+
"a b c",
|
|
302
|
+
"A B C"
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
case!(
|
|
306
|
+
abc_lower_me,
|
|
307
|
+
Case::Lower,
|
|
308
|
+
Locale::EN,
|
|
309
|
+
StyleGuide::LanguageDefault,
|
|
310
|
+
"A B C",
|
|
311
|
+
"a b c"
|
|
312
|
+
);
|
|
313
|
+
|
|
247
314
|
macro_rules! titlecase {
|
|
248
315
|
($name:ident, $locale:expr, $style:expr, $input:expr, $expected:expr) => {
|
|
249
316
|
#[test]
|
|
@@ -254,116 +321,122 @@ mod tests {
|
|
|
254
321
|
};
|
|
255
322
|
}
|
|
256
323
|
|
|
257
|
-
titlecase!(
|
|
324
|
+
titlecase!(
|
|
325
|
+
abc_none,
|
|
326
|
+
Locale::EN,
|
|
327
|
+
StyleGuide::LanguageDefault,
|
|
328
|
+
"a b c",
|
|
329
|
+
"A B C"
|
|
330
|
+
);
|
|
258
331
|
|
|
259
332
|
titlecase!(
|
|
260
333
|
abc_cmos,
|
|
261
|
-
|
|
262
|
-
|
|
334
|
+
Locale::EN,
|
|
335
|
+
StyleGuide::ChicagoManualOfStyle,
|
|
263
336
|
"a b c",
|
|
264
337
|
"A B C"
|
|
265
338
|
);
|
|
266
339
|
|
|
267
340
|
titlecase!(
|
|
268
341
|
abc_gruber,
|
|
269
|
-
|
|
270
|
-
|
|
342
|
+
Locale::EN,
|
|
343
|
+
StyleGuide::DaringFireball,
|
|
271
344
|
"a b c",
|
|
272
345
|
"A B C"
|
|
273
346
|
);
|
|
274
347
|
|
|
275
348
|
titlecase!(
|
|
276
349
|
simple_cmos,
|
|
277
|
-
|
|
278
|
-
|
|
350
|
+
Locale::EN,
|
|
351
|
+
StyleGuide::ChicagoManualOfStyle,
|
|
279
352
|
"Once UPON A time",
|
|
280
353
|
"Once upon a Time"
|
|
281
354
|
);
|
|
282
355
|
|
|
283
356
|
titlecase!(
|
|
284
357
|
simple_gruber,
|
|
285
|
-
|
|
286
|
-
|
|
358
|
+
Locale::EN,
|
|
359
|
+
StyleGuide::DaringFireball,
|
|
287
360
|
"Once UPON A time",
|
|
288
361
|
"Once UPON a Time"
|
|
289
362
|
);
|
|
290
363
|
|
|
291
364
|
titlecase!(
|
|
292
365
|
colon_cmos,
|
|
293
|
-
|
|
294
|
-
|
|
366
|
+
Locale::EN,
|
|
367
|
+
StyleGuide::ChicagoManualOfStyle,
|
|
295
368
|
"foo: a baz",
|
|
296
369
|
"Foo: a Baz"
|
|
297
370
|
);
|
|
298
371
|
|
|
299
372
|
titlecase!(
|
|
300
373
|
colon_gruber,
|
|
301
|
-
|
|
302
|
-
|
|
374
|
+
Locale::EN,
|
|
375
|
+
StyleGuide::DaringFireball,
|
|
303
376
|
"foo: a baz",
|
|
304
377
|
"Foo: A Baz"
|
|
305
378
|
);
|
|
306
379
|
|
|
307
380
|
// titlecase!(
|
|
308
381
|
// qna_cmos,
|
|
309
|
-
//
|
|
310
|
-
//
|
|
382
|
+
// Locale::EN,
|
|
383
|
+
// StyleGuide::ChicagoManualOfStyle,
|
|
311
384
|
// "Q&A with Steve Jobs: 'That's what happens in technology'",
|
|
312
385
|
// "Q&a with Steve Jobs: 'that's What Happens in Technology'"
|
|
313
386
|
// );
|
|
314
387
|
|
|
315
388
|
titlecase!(
|
|
316
389
|
qna_gruber,
|
|
317
|
-
|
|
318
|
-
|
|
390
|
+
Locale::EN,
|
|
391
|
+
StyleGuide::DaringFireball,
|
|
319
392
|
"Q&A with Steve Jobs: 'That's what happens in technology'",
|
|
320
393
|
"Q&A With Steve Jobs: 'That's What Happens in Technology'"
|
|
321
394
|
);
|
|
322
395
|
|
|
323
396
|
titlecase!(
|
|
324
397
|
ws_gruber,
|
|
325
|
-
|
|
326
|
-
|
|
398
|
+
Locale::EN,
|
|
399
|
+
StyleGuide::DaringFireball,
|
|
327
400
|
" free trolling\n space ",
|
|
328
401
|
" Free Trolling\n Space "
|
|
329
402
|
);
|
|
330
403
|
|
|
331
404
|
titlecase!(
|
|
332
405
|
turkish_question,
|
|
333
|
-
|
|
334
|
-
|
|
406
|
+
Locale::TR,
|
|
407
|
+
StyleGuide::LanguageDefault,
|
|
335
408
|
"aç mısın",
|
|
336
409
|
"Aç mısın"
|
|
337
410
|
);
|
|
338
411
|
|
|
339
412
|
titlecase!(
|
|
340
413
|
turkish_question_false,
|
|
341
|
-
|
|
342
|
-
|
|
414
|
+
Locale::TR,
|
|
415
|
+
StyleGuide::LanguageDefault,
|
|
343
416
|
"dualarımızda minnettarlık",
|
|
344
417
|
"Dualarımızda Minnettarlık"
|
|
345
418
|
);
|
|
346
419
|
|
|
347
420
|
titlecase!(
|
|
348
421
|
turkish_chars,
|
|
349
|
-
|
|
350
|
-
|
|
422
|
+
Locale::TR,
|
|
423
|
+
StyleGuide::LanguageDefault,
|
|
351
424
|
"İLKİ ILIK ÖĞLEN",
|
|
352
425
|
"İlki Ilık Öğlen"
|
|
353
426
|
);
|
|
354
427
|
|
|
355
428
|
titlecase!(
|
|
356
429
|
turkish_blockwords,
|
|
357
|
-
|
|
358
|
-
|
|
430
|
+
Locale::TR,
|
|
431
|
+
StyleGuide::LanguageDefault,
|
|
359
432
|
"Sen VE ben ile o",
|
|
360
433
|
"Sen ve Ben ile O"
|
|
361
434
|
);
|
|
362
435
|
|
|
363
436
|
titlecase!(
|
|
364
437
|
turkish_ws,
|
|
365
|
-
|
|
366
|
-
|
|
438
|
+
Locale::TR,
|
|
439
|
+
StyleGuide::LanguageDefault,
|
|
367
440
|
" serbest serseri\n boşluk ",
|
|
368
441
|
" Serbest Serseri\n Boşluk "
|
|
369
442
|
);
|
|
@@ -378,16 +451,11 @@ mod tests {
|
|
|
378
451
|
};
|
|
379
452
|
}
|
|
380
453
|
|
|
381
|
-
lowercase!(
|
|
382
|
-
lower_en,
|
|
383
|
-
InputLocale::EN,
|
|
384
|
-
"foo BAR BaZ BIKE",
|
|
385
|
-
"foo bar baz bike"
|
|
386
|
-
);
|
|
454
|
+
lowercase!(lower_en, Locale::EN, "foo BAR BaZ BIKE", "foo bar baz bike");
|
|
387
455
|
|
|
388
456
|
lowercase!(
|
|
389
457
|
lower_tr,
|
|
390
|
-
|
|
458
|
+
Locale::TR,
|
|
391
459
|
"foo BAR BaZ ILIK İLE",
|
|
392
460
|
"foo bar baz ılık ile"
|
|
393
461
|
);
|
|
@@ -402,16 +470,11 @@ mod tests {
|
|
|
402
470
|
};
|
|
403
471
|
}
|
|
404
472
|
|
|
405
|
-
uppercase!(
|
|
406
|
-
upper_en,
|
|
407
|
-
InputLocale::EN,
|
|
408
|
-
"foo BAR BaZ bike",
|
|
409
|
-
"FOO BAR BAZ BIKE"
|
|
410
|
-
);
|
|
473
|
+
uppercase!(upper_en, Locale::EN, "foo BAR BaZ bike", "FOO BAR BAZ BIKE");
|
|
411
474
|
|
|
412
475
|
uppercase!(
|
|
413
476
|
upper_tr,
|
|
414
|
-
|
|
477
|
+
Locale::TR,
|
|
415
478
|
"foo BAR BaZ ILIK İLE",
|
|
416
479
|
"FOO BAR BAZ ILIK İLE"
|
|
417
480
|
);
|
|
@@ -428,15 +491,10 @@ mod tests {
|
|
|
428
491
|
|
|
429
492
|
sentencecase!(
|
|
430
493
|
sentence_en,
|
|
431
|
-
|
|
494
|
+
Locale::EN,
|
|
432
495
|
"insert BIKE here",
|
|
433
496
|
"Insert bike here"
|
|
434
497
|
);
|
|
435
498
|
|
|
436
|
-
sentencecase!(
|
|
437
|
-
sentence_tr,
|
|
438
|
-
InputLocale::TR,
|
|
439
|
-
"ilk DAVRANSIN",
|
|
440
|
-
"İlk davransın"
|
|
441
|
-
);
|
|
499
|
+
sentencecase!(sentence_tr, Locale::TR, "ilk DAVRANSIN", "İlk davransın");
|
|
442
500
|
}
|