unic_cli/
writers.rs

1// Copyright 2017 The UNIC Project Developers.
2//
3// See the COPYRIGHT file at the top-level directory of this distribution.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use std::io;
12use std::str::Chars;
13
14use super::Result;
15
16// TODO(FUTURE_RUST): Replace with char::MAX_UTF*_LEN when available.
17const MAX_UTF8_LEN: usize = 4; // x u8 per char
18const MAX_UTF16_LEN: usize = 2; // x u16 per char
19
20macro_rules! write_join_with_space {
21    ($output:expr, $values:expr, $write_fn:expr) => {{
22        let mut first = true;
23        for v in $values {
24            if !first {
25                write!($output, " ")?;
26            }
27            first = false;
28            ($write_fn)($output, v)?;
29        }
30        Ok(())
31    }};
32}
33
34// == Single Char ==
35
36pub fn write_char_as_codepoint<W: io::Write>(output: &mut W, ch: char) -> Result<()> {
37    write!(output, "U+{:04X}", ch as u32)
38}
39
40pub fn write_char_as_utf8_hex<W: io::Write>(output: &mut W, ch: char) -> Result<()> {
41    let mut buf = [0; MAX_UTF8_LEN];
42    let utf8 = ch.encode_utf8(&mut buf).as_bytes();
43    write_join_with_space!(output, utf8.iter(), |output: &mut W, b8| -> Result<()> {
44        write!(output, "0x{:02X}", b8)
45    })
46}
47
48pub fn write_char_as_utf16_hex<W: io::Write>(output: &mut W, ch: char) -> Result<()> {
49    let mut buf = [0; MAX_UTF16_LEN];
50    let utf16 = ch.encode_utf16(&mut buf);
51    write_join_with_space!(output, utf16.iter(), |output: &mut W, b16| -> Result<()> {
52        write!(output, "0x{:04X}", b16)
53    })
54}
55
56// == Multiple Chars ==
57
58pub fn write_as_codepoints<'a, W: io::Write>(output: &mut W, chars: Chars<'a>) -> Result<()> {
59    write_join_with_space!(output, chars, write_char_as_codepoint)
60}
61
62pub fn write_as_utf8_hex<'a, W: io::Write>(output: &mut W, chars: Chars<'a>) -> Result<()> {
63    write_join_with_space!(output, chars, write_char_as_utf8_hex)
64}
65
66pub fn write_as_utf16_hex<'a, W: io::Write>(output: &mut W, chars: Chars<'a>) -> Result<()> {
67    write_join_with_space!(output, chars, write_char_as_utf16_hex)
68}
69
70pub fn write_with_control_n_unicode_braces_escape<'a, W: io::Write>(
71    output: &mut W,
72    chars: Chars<'a>,
73) -> Result<()> {
74    write!(output, "\"")?;
75    for ch in chars {
76        write!(output, "{}", ch.escape_default())?;
77    }
78    write!(output, "\"")?;
79    Ok(())
80}
81
82pub fn write_with_control_braces_escape<'a, W: io::Write>(
83    output: &mut W,
84    chars: Chars<'a>,
85) -> Result<()> {
86    write!(output, "\"")?;
87    for ch in chars {
88        write!(output, "{}", ch.escape_debug())?;
89    }
90    write!(output, "\"")?;
91    Ok(())
92}
93
94pub fn write_with_all_braces_escape<'a, W: io::Write>(
95    output: &mut W,
96    chars: Chars<'a>,
97) -> Result<()> {
98    write!(output, "\"")?;
99    for ch in chars {
100        write!(output, "{}", ch.escape_unicode())?;
101    }
102    write!(output, "\"")?;
103    Ok(())
104}