Skip to main content

sejong/syllable/
final_consonant.rs

1use super::{Byte, InitialConsonant};
2use std::convert::{TryFrom, TryInto};
3
4#[derive(Clone, Copy, PartialEq, Debug)]
5#[repr(u8)]
6pub(crate) enum FinalConsonant {
7    None,
8    G,  // ㄱ
9    KK, // ㄲ
10    GS, // ㄳ
11    N,  // ㄴ
12    NJ, // ㄵ
13    NH, // ㄶ
14    D,  // ㄷ
15    L,  // ㄹ
16    LG, // ㄺ
17    LM, // ㄻ
18    LB, // ㄼ
19    LS, // ㄽ
20    LT, // ㄾ
21    LP, // ㄿ
22    LH, // ㅀ
23    M,  // ㅁ
24    B,  // ㅂ
25    BS, // ㅄ
26    S,  // ㅅ
27    SS, // ㅆ
28    NG, // ㅇ
29    J,  // ㅈ
30    CH, // ㅊ
31    K,  // ㅋ
32    T,  // ㅌ
33    P,  // ㅍ
34    H,  // ㅎ
35}
36
37impl TryFrom<Byte> for FinalConsonant {
38    type Error = Byte;
39    fn try_from(b: Byte) -> Result<Self, Self::Error> {
40        match b {
41            Byte::G => Ok(Self::G),
42            Byte::KK => Ok(Self::KK),
43            Byte::N => Ok(Self::N),
44            Byte::D => Ok(Self::D),
45            Byte::R => Ok(Self::L),
46            Byte::M => Ok(Self::M),
47            Byte::B => Ok(Self::B),
48            Byte::S => Ok(Self::S),
49            Byte::SS => Ok(Self::SS),
50            Byte::NG => Ok(Self::NG),
51            Byte::J => Ok(Self::J),
52            Byte::CH => Ok(Self::CH),
53            Byte::K => Ok(Self::K),
54            Byte::T => Ok(Self::T),
55            Byte::P => Ok(Self::P),
56            Byte::H => Ok(Self::H),
57            _ => Err(b),
58        }
59    }
60}
61
62impl TryFrom<(Self, Byte)> for FinalConsonant {
63    type Error = (Self, Byte);
64    fn try_from(input: (Self, Byte)) -> Result<Self, Self::Error> {
65        match input.0 {
66            Self::G => match input.1 {
67                Byte::S => Ok(Self::GS),
68                _ => Err(input),
69            },
70            Self::N => match input.1 {
71                Byte::J => Ok(Self::NJ),
72                Byte::H => Ok(Self::NH),
73                _ => Err(input),
74            },
75            Self::L => match input.1 {
76                Byte::G => Ok(Self::LG),
77                Byte::M => Ok(Self::LM),
78                Byte::B => Ok(Self::LB),
79                Byte::S => Ok(Self::LS),
80                Byte::T => Ok(Self::LT),
81                Byte::P => Ok(Self::LP),
82                Byte::H => Ok(Self::LH),
83                _ => Err(input),
84            },
85            Self::B => match input.1 {
86                Byte::S => Ok(Self::BS),
87                _ => Err(input),
88            },
89            _ => Err(input),
90        }
91    }
92}
93
94impl Default for FinalConsonant {
95    fn default() -> Self {
96        Self::None
97    }
98}
99
100impl TryInto<(Self, InitialConsonant)> for FinalConsonant {
101    type Error = Self;
102    fn try_into(self) -> Result<(Self, InitialConsonant), Self> {
103        match self {
104            Self::GS => Ok((Self::G, InitialConsonant::S)),
105            Self::NJ => Ok((Self::N, InitialConsonant::J)),
106            Self::NH => Ok((Self::N, InitialConsonant::H)),
107            Self::LG => Ok((Self::L, InitialConsonant::G)),
108            Self::LM => Ok((Self::L, InitialConsonant::M)),
109            Self::LB => Ok((Self::L, InitialConsonant::B)),
110            Self::LS => Ok((Self::L, InitialConsonant::S)),
111            Self::LT => Ok((Self::L, InitialConsonant::T)),
112            Self::LP => Ok((Self::L, InitialConsonant::P)),
113            Self::LH => Ok((Self::L, InitialConsonant::H)),
114            Self::BS => Ok((Self::B, InitialConsonant::S)),
115            _ => Err(self),
116        }
117    }
118}
119
120impl FinalConsonant {
121    pub fn try_remove_second_half(self) -> Option<Self> {
122        match self {
123            Self::GS => Some(Self::G),
124            Self::NJ | Self::NH => Some(Self::N),
125            Self::LG | Self::LM | Self::LB | Self::LS | Self::LT | Self::LP | Self::LH => {
126                Some(Self::L)
127            }
128            Self::BS => Some(Self::B),
129            _ => None,
130        }
131    }
132}