sapi_lite/tts/speech/types.rs
1use std::fmt::Display;
2use std::hash::Hash;
3
4/// Provides a hint about how to pronounce the associated content.
5#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
6pub enum SayAs<'s> {
7 /// Pronounce a sequence of numbers as a date, e.g. "03/08/2000" as "march eighth two thousand".
8 DateMDY,
9 /// Pronounce a sequence of numbers as a date, e.g. "03/08/2000" as "august third two thousand".
10 DateDMY,
11 /// Pronounce a sequence of numbers as a date, e.g. "2000/08/03" as "march eighth two thousand".
12 DateYMD,
13 /// Pronounce a sequence of numbers as a year and month, e.g. "2000/03" as "march two thousand".
14 DateYM,
15 /// Pronounce a sequence of numbers as a month and year, e.g. "03/2000" as "march two thousand".
16 DateMY,
17 /// Pronounce a sequence of numbers as a day and month, e.g. "03/08" as "march eighth".
18 DateDM,
19 /// Pronounce a sequence of numbers as a month and day, e.g. "03/08" as "august third".
20 DateMD,
21 /// Pronounce a number as a year, e.g. "1979" as "nineteen seventy-nine".
22 DateYear,
23 /// Pronounce a sequence of numbers as a time, e.g. "10:24" as "ten twenty-four".
24 Time,
25 /// Pronounce a number as a cardinal number, e.g. "1024" as "one thousand twenty-four".
26 NumberCardinal,
27 /// Pronounce a number as a sequence of digits, e.g. "1024" as "one zero two four".
28 NumberDigit,
29 /// Pronounce a number as a fraction, e.g. "3/8" as "three eighths".
30 NumberFraction,
31 /// Pronounce a number as a fraction, e.g. "10.24" as "ten point two four".
32 NumberDecimal,
33 /// Pronounce a sequence of numbers as a telephone, e.g. "(206) 555-1234" as "two zero six five
34 /// five five one two three four".
35 PhoneNumber,
36 /// A custom pronunciation hint supported by the engine.
37 Custom(&'s str),
38}
39
40impl<'s> SayAs<'s> {
41 pub(super) fn sapi_id(&self) -> &str {
42 match self {
43 Self::DateMDY => "date_mdy",
44 Self::DateDMY => "date_dmy",
45 Self::DateYMD => "date_ymd",
46 Self::DateYM => "date_ym",
47 Self::DateMY => "date_my",
48 Self::DateDM => "date_dm",
49 Self::DateMD => "date_md",
50 Self::DateYear => "date_year",
51 Self::Time => "time",
52 Self::NumberCardinal => "number_cardinal",
53 Self::NumberDigit => "number_digit",
54 Self::NumberFraction => "number_fraction",
55 Self::NumberDecimal => "number_decimal",
56 Self::PhoneNumber => "phone_number",
57 Self::Custom(s) => s,
58 }
59 }
60}
61
62macro_rules! decl_clamped_int {
63 {$(#[$meta:meta])* $name:ident($base:ty) in $min:literal..$max:literal} => {
64 $(#[$meta])*
65 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
66 pub struct $name($base);
67
68 impl $name {
69 /// Clamps the given value to the interval
70 #[doc = concat!("[", stringify!($min), ", ", stringify!($max), "]")]
71 /// and constructs a new instance from it.
72 pub fn new(value: $base) -> Self {
73 Self(value.clamp($min, $max))
74 }
75
76 /// Returns the value encapsulated by this instance.
77 pub fn value(&self) -> $base {
78 self.0
79 }
80 }
81
82 impl From<$base> for $name {
83 fn from(source: $base) -> Self {
84 Self::new(source)
85 }
86 }
87
88 impl From<$name> for $base {
89 fn from(source: $name) -> Self {
90 source.0
91 }
92 }
93
94 impl Display for $name {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 write!(f, "{}", self.0)
97 }
98 }
99 };
100}
101
102decl_clamped_int! {
103 /// Voice pitch, represented as a value in the interval [-10, 10], with 0 being normal pitch.
104 Pitch(i32) in -10..10
105}
106
107decl_clamped_int! {
108 /// Speech rate, represented as a value in the interval [-10, 10], with 0 being normal speed.
109 Rate(i32) in -10..10
110}
111
112decl_clamped_int! {
113 /// Voice volume, represented as a value in the interval [0, 100], with 100 being full volume.
114 Volume(u32) in 0..100
115}
116
117impl Volume {
118 pub(crate) fn from_sapi(source: u16) -> Self {
119 Self::new(source as _)
120 }
121
122 pub(crate) fn sapi_value(&self) -> u16 {
123 self.0 as _
124 }
125}