Skip to main content

pito_tui/
copy.rs

1use std::io::{self, Write};
2
3pub const COPY_MAX: usize = 48 * 1024;
4
5pub fn copy(text: &str) -> bool {
6    if text.len() > COPY_MAX {
7        return false;
8    }
9    let mut out = io::stdout();
10    write!(out, "\x1b]52;c;{}\x07", base64(text.as_bytes())).is_ok() && out.flush().is_ok()
11}
12
13pub fn base64(bytes: &[u8]) -> String {
14    const ABC: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
15    let mut out = String::with_capacity(bytes.len().div_ceil(3) * 4);
16    for chunk in bytes.chunks(3) {
17        let b = [
18            chunk[0],
19            *chunk.get(1).unwrap_or(&0),
20            *chunk.get(2).unwrap_or(&0),
21        ];
22        let n = (u32::from(b[0]) << 16) | (u32::from(b[1]) << 8) | u32::from(b[2]);
23        for k in 0..4 {
24            if k <= chunk.len() {
25                out.push(ABC[(n >> (18 - 6 * k) & 63) as usize] as char);
26            } else {
27                out.push('=');
28            }
29        }
30    }
31    out
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn base64_matches_the_standard_alphabet() {
40        assert_eq!(base64(b""), "");
41        assert_eq!(base64(b"f"), "Zg==");
42        assert_eq!(base64(b"fo"), "Zm8=");
43        assert_eq!(base64(b"foo"), "Zm9v");
44        assert_eq!(base64("panic: ΓΌ".as_bytes()), "cGFuaWM6IMO8");
45    }
46}