fish-shell/src/wchar.rs

56 lines
1.9 KiB
Rust
Raw Normal View History

2023-02-05 00:02:42 +00:00
//! Support for wide strings.
//!
//! There are two wide string types that are commonly used:
//! - wstr: a string slice without a nul terminator. Like `&str` but wide chars.
//! - WString: an owning string without a nul terminator. Like `String` but wide chars.
use crate::common::{ENCODE_DIRECT_BASE, ENCODE_DIRECT_END};
2023-01-14 22:56:24 +00:00
pub use widestring::{Utf32Str as wstr, Utf32String as WString};
/// Pull in our extensions.
pub use crate::wchar_ext::IntoCharIter;
pub mod prelude {
pub use crate::{
wchar::{wstr, IntoCharIter, WString, L},
wchar_ext::{ToWString, WExt},
wutil::{sprintf, wgettext, wgettext_fmt, wgettext_maybe_fmt, wgettext_str},
};
}
2023-01-14 22:56:24 +00:00
/// Creates a wstr string slice, like the "L" prefix of C++.
/// The result is of type wstr.
/// It is NOT nul-terminated.
#[macro_export]
2023-01-14 22:56:24 +00:00
macro_rules! L {
($string:expr) => {
2023-01-14 22:56:24 +00:00
widestring::utf32str!($string)
};
}
pub use L;
2023-01-14 22:56:24 +00:00
2023-02-05 21:08:32 +00:00
/// Encode a literal byte in a UTF-32 character. This is required for e.g. the echo builtin, whose
/// escape sequences can be used to construct raw byte sequences which are then interpreted as e.g.
/// UTF-8 by the terminal. If we were to interpret each of those bytes as a codepoint and encode it
/// as a UTF-32 character, printing them would result in several characters instead of one UTF-8
/// character.
///
/// See https://github.com/fish-shell/fish-shell/issues/1894.
pub fn encode_byte_to_char(byte: u8) -> char {
2023-03-11 02:47:41 +00:00
char::from_u32(u32::from(ENCODE_DIRECT_BASE) + u32::from(byte))
2023-02-05 21:08:32 +00:00
.expect("private-use codepoint should be valid char")
}
/// Decode a literal byte from a UTF-32 character.
pub fn decode_byte_from_char(c: char) -> Option<u8> {
if c >= ENCODE_DIRECT_BASE && c < ENCODE_DIRECT_END {
Some(
(u32::from(c) - u32::from(ENCODE_DIRECT_BASE))
.try_into()
.unwrap(),
)
} else {
None
}
}