1#[derive(Debug)]
2pub(crate) struct FontPreference {
3 pub name: String,
4 pub style: Option<String>,
5 pub pt_size: f32,
6}
7
8impl Default for FontPreference {
9 fn default() -> Self {
10 Self {
11 name: "sans-serif".into(),
12 style: None,
13 pt_size: 10.0,
14 }
15 }
16}
17
18impl FontPreference {
19 /// Parse config string like `Cantarell 12`, `Cantarell Bold 11`, `Noto Serif CJK HK Bold 12`.
20 pub fn from_name_style_size(conf: &str) -> Option<Self> {
21 // assume last is size, 2nd last is style and the rest is name.
22 match conf.rsplit_once(' ') {
23 Some((head, tail)) if tail.chars().all(|c| c.is_numeric()) => {
24 let pt_size: f32 = tail.parse().unwrap_or(10.0);
25 match head.rsplit_once(' ') {
26 Some((name, style)) if !name.is_empty() => Some(Self {
27 name: name.into(),
28 style: Some(style.into()),
29 pt_size,
30 }),
31 None if !head.is_empty() => Some(Self {
32 name: head.into(),
33 style: None,
34 pt_size,
35 }),
36 _ => None,
37 }
38 }
39 Some((head, tail)) if !head.is_empty() => Some(Self {
40 name: head.into(),
41 style: Some(tail.into()),
42 pt_size: 10.0,
43 }),
44 None if !conf.is_empty() => Some(Self {
45 name: conf.into(),
46 style: None,
47 pt_size: 10.0,
48 }),
49 _ => None,
50 }
51 }
52}
53
54#[test]
55fn pref_from_multi_name_variant_size() {
56 let pref: FontPreference = FontPreference::from_name_style_size(conf:"Noto Serif CJK HK Bold 12").unwrap();
57 assert_eq!(pref.name, "Noto Serif CJK HK");
58 assert_eq!(pref.style, Some("Bold".into()));
59 assert!((pref.pt_size - 12.0).abs() < f32::EPSILON);
60}
61
62#[test]
63fn pref_from_name_variant_size() {
64 let pref: FontPreference = FontPreference::from_name_style_size(conf:"Cantarell Bold 12").unwrap();
65 assert_eq!(pref.name, "Cantarell");
66 assert_eq!(pref.style, Some("Bold".into()));
67 assert!((pref.pt_size - 12.0).abs() < f32::EPSILON);
68}
69
70#[test]
71fn pref_from_name_size() {
72 let pref: FontPreference = FontPreference::from_name_style_size(conf:"Cantarell 12").unwrap();
73 assert_eq!(pref.name, "Cantarell");
74 assert_eq!(pref.style, None);
75 assert!((pref.pt_size - 12.0).abs() < f32::EPSILON);
76}
77
78#[test]
79fn pref_from_name() {
80 let pref: FontPreference = FontPreference::from_name_style_size(conf:"Cantarell").unwrap();
81 assert_eq!(pref.name, "Cantarell");
82 assert_eq!(pref.style, None);
83 assert!((pref.pt_size - 10.0).abs() < f32::EPSILON);
84}
85#[test]
86fn pref_from_multi_name_style() {
87 let pref: FontPreference = FontPreference::from_name_style_size(conf:"Foo Bar Baz Bold").unwrap();
88 assert_eq!(pref.name, "Foo Bar Baz");
89 assert_eq!(pref.style, Some("Bold".into()));
90 assert!((pref.pt_size - 10.0).abs() < f32::EPSILON);
91}
92