work on character encoding
[pspp] / rust / src / encoding.rs
1 include!(concat!(env!("OUT_DIR"), "/encodings.rs"));
2
3 pub fn codepage_from_encoding(encoding: &str) -> Option<u32> {
4     CODEPAGE_NAME_TO_NUMBER
5         .get(encoding.to_ascii_lowercase().as_str())
6         .copied()
7 }
8
9 use thiserror::Error as ThisError;
10 #[derive(ThisError, Debug)]
11 pub enum Error {
12     #[error("This system file does not indicate its own character encoding.  xFor best results, specify an encoding explicitly.  Use SYSFILE INFO with ENCODING=\"DETECT\" to analyze the possible encodings.")]
13     NoEncoding,
14
15     #[error("This system file encodes text strings with unknown code page {0}.")]
16     UnknownCodepage(u32),
17
18     #[error("This system file is encoded in EBCDIC, which is not supported.")]
19     Ebcdic,
20 }
21
22 /// Returns the character set used by the locale configured in the operating
23 /// system.  This should implement roughly the same behavior as the function
24 /// with the same name in Gnulib.  Until then, we'll just use a default.
25 pub fn locale_charset() -> &'static str {
26     "UTF-8"
27 }
28
29 pub fn get_encoding(encoding: Option<&str>, character_code: Option<u32>) -> Result<&str, Error> {
30     if let Some(encoding) = encoding {
31         Ok(encoding)
32     } else if let Some(codepage) = character_code {
33         match codepage {
34             1 => Err(Error::Ebcdic),
35             2 | 3 => {
36                 // These ostensibly mean "7-bit ASCII" and "8-bit ASCII"[sic]
37                 // respectively.  However, many files have character code 2 but
38                 // data which are clearly not ASCII.  Therefore, ignore these
39                 // values.
40                 Err(Error::NoEncoding)
41             }
42             4 => Ok("MS_KANJI"),
43             _ => CODEPAGE_NUMBER_TO_NAME
44                 .get(&codepage)
45                 .copied()
46                 .ok_or(Error::UnknownCodepage(codepage)),
47         }
48     } else {
49         Err(Error::NoEncoding)
50     }
51 }