Skip to content

Commit efea82d

Browse files
committed
feat(macro): add langtag! macro
increase version to 0.0.4
1 parent 2308269 commit efea82d

File tree

4 files changed

+146
-1
lines changed

4 files changed

+146
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "language-tags"
3-
version = "0.0.3"
3+
version = "0.0.4"
44
authors = ["Pyfisch <[email protected]>"]
55

66
description = "Language tags for Rust"

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,5 @@ let mut langtag2: LanguageTag = Default::default();
4747
langtag2.language = Some("de".to_owned());
4848
assert!(langtag2.matches(&langtag1));
4949
```
50+
51+
There is also the `langtag!` macro for creating language tags.

src/lib.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
//! langtag2.language = Some("de".to_owned());
4949
//! assert!(langtag2.matches(&langtag1));
5050
//! ```
51+
//!
52+
//! There is also the `langtag!` macro for creating language tags.
5153
5254
use std::ascii::AsciiExt;
5355
use std::collections::BTreeMap;
@@ -387,3 +389,106 @@ impl fmt::Display for LanguageTag {
387389
Ok(())
388390
}
389391
}
392+
393+
#[macro_export]
394+
/// Utility for creating simple language tags.
395+
///
396+
/// The macro supports the language, exlang, script and region parts of language tags,
397+
/// they are separated by semicolons, omitted parts are denoted with mulitple semicolons.
398+
///
399+
/// # Examples
400+
/// * `it`: `langtag!(it)`
401+
/// * `it-LY`: `langtag!(it;;;LY)`
402+
/// * `it-Arab-LY`: `langtag!(it;;Arab;LY)`
403+
/// * `ar-afb`: `langtag!(ar;afb)`
404+
/// * `i-enochian`: `langtag!(i-enochian)`
405+
macro_rules! langtag {
406+
( $language:expr ) => {
407+
LanguageTag {
408+
language: Some(stringify!($language).to_owned()),
409+
extlang: None,
410+
script: None,
411+
region: None,
412+
variants: Vec::new(),
413+
extensions: BTreeMap::new(),
414+
privateuse: Vec::new(),
415+
}
416+
};
417+
( $language:expr;;;$region:expr ) => {
418+
LanguageTag {
419+
language: Some(stringify!($language).to_owned()),
420+
extlang: None,
421+
script: None,
422+
region: Some(stringify!($region).to_owned()),
423+
variants: Vec::new(),
424+
extensions: BTreeMap::new(),
425+
privateuse: Vec::new(),
426+
}
427+
};
428+
( $language:expr;;$script:expr ) => {
429+
LanguageTag {
430+
language: Some(stringify!($language).to_owned()),
431+
extlang: None,
432+
script: Some(stringify!($script).to_owned()),
433+
region: None,
434+
variants: Vec::new(),
435+
extensions: BTreeMap::new(),
436+
privateuse: Vec::new(),
437+
}
438+
};
439+
( $language:expr;;$script:expr;$region:expr ) => {
440+
LanguageTag {
441+
language: Some(stringify!($language).to_owned()),
442+
extlang: None,
443+
script: Some(stringify!($script).to_owned()),
444+
region: Some(stringify!($region).to_owned()),
445+
variants: Vec::new(),
446+
extensions: BTreeMap::new(),
447+
privateuse: Vec::new(),
448+
}
449+
};
450+
( $language:expr;$extlang:expr) => {
451+
LanguageTag {
452+
language: Some(stringify!($language).to_owned()),
453+
extlang: Some(stringify!($extlang).to_owned()),
454+
script: None,
455+
region: None,
456+
variants: Vec::new(),
457+
extensions: BTreeMap::new(),
458+
privateuse: Vec::new(),
459+
}
460+
};
461+
( $language:expr;$extlang:expr;$script:expr) => {
462+
LanguageTag {
463+
language: Some(stringify!($language).to_owned()),
464+
extlang: Some(stringify!($extlang).to_owned()),
465+
script: Some(stringify!($script).to_owned()),
466+
region: None,
467+
variants: Vec::new(),
468+
extensions: BTreeMap::new(),
469+
privateuse: Vec::new(),
470+
}
471+
};
472+
( $language:expr;$extlang:expr;;$region:expr ) => {
473+
LanguageTag {
474+
language: Some(stringify!($language).to_owned()),
475+
extlang: Some(stringify!($extlang).to_owned()),
476+
script: None,
477+
region: Some(stringify!($region).to_owned()),
478+
variants: Vec::new(),
479+
extensions: BTreeMap::new(),
480+
privateuse: Vec::new(),
481+
}
482+
};
483+
( $language:expr;$extlang:expr;$script:expr;$region:expr ) => {
484+
LanguageTag {
485+
language: Some(stringify!($language).to_owned()),
486+
extlang: Some(stringify!($extlang).to_owned()),
487+
script: Some(stringify!($script).to_owned()),
488+
region: Some(stringify!($region).to_owned()),
489+
variants: Vec::new(),
490+
extensions: BTreeMap::new(),
491+
privateuse: Vec::new(),
492+
}
493+
};
494+
}

tests/tests.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[macro_use]
12
extern crate language_tags;
23

34
use std::default::Default;
@@ -131,6 +132,43 @@ fn test_format() {
131132
assert_eq!(format!("{}", y), "MgxQa-ywEp-8lcW-7bvT-h-dP1Md-0h7-0Z3ir");
132133
}
133134

135+
#[test]
136+
fn test_macro() {
137+
let a1 = langtag!(it);
138+
let a2 = LanguageTag {
139+
language: Some("it".to_owned()),
140+
extlang: None,
141+
script: None,
142+
region: None,
143+
variants: Vec::new(),
144+
extensions: BTreeMap::new(),
145+
privateuse: Vec::new(),
146+
};
147+
assert_eq!(a1, a2);
148+
let b1 = langtag!(it;;;LY);
149+
let b2 = LanguageTag {
150+
language: Some("it".to_owned()),
151+
extlang: None,
152+
script: None,
153+
region: Some("LY".to_owned()),
154+
variants: Vec::new(),
155+
extensions: BTreeMap::new(),
156+
privateuse: Vec::new(),
157+
};
158+
assert_eq!(b1, b2);
159+
let c1 = langtag!(it;;Arab;LY);
160+
let c2 = LanguageTag {
161+
language: Some("it".to_owned()),
162+
extlang: None,
163+
script: Some("Arab".to_owned()),
164+
region: Some("LY".to_owned()),
165+
variants: Vec::new(),
166+
extensions: BTreeMap::new(),
167+
privateuse: Vec::new(),
168+
};
169+
assert_eq!(c1, c2);
170+
}
171+
134172
#[test]
135173
fn test_wellformed_tags() {
136174
// Source: http://www.langtag.net/test-suites/well-formed-tags.txt

0 commit comments

Comments
 (0)