xvc_core/util/
mod.rs

1//! Various utility functions
2pub mod completer;
3pub mod file;
4pub mod git;
5pub mod pmp;
6pub mod serde;
7pub mod store;
8pub mod xvcignore;
9
10use std::collections::HashMap;
11use std::io::{self, Read};
12use std::thread::sleep;
13use std::time::Duration;
14
15use crossbeam_channel::{bounded, Receiver};
16
17use crate::error::Result;
18use crate::{XvcMetadata, XvcPath, CHANNEL_BOUND};
19
20/// A hashmap to store [XvcMetadata] for [XvcPath]
21pub type XvcPathMetadataMap = HashMap<XvcPath, XvcMetadata>;
22
23/// Converts stdin input to a channel.
24///
25/// It works by creating a thread inside.
26///
27/// WARNING:
28///     Stdin is normally blocking the thread.
29///     The thread may continue to live if there is no input in stdin.
30///     A future version may also return the thread handle to prevent this.
31pub fn stdin_channel() -> Receiver<String> {
32    let (input_snd, input_rec) = bounded::<String>(CHANNEL_BOUND);
33    crossbeam::scope(|s| {
34        s.spawn(move |_| -> Result<()> {
35            let stdin = io::stdin();
36            loop {
37                if input_snd.try_send("".into()).is_err() {
38                    break;
39                }
40                let mut input = stdin.lock();
41                let mut buf = Vec::<u8>::new();
42                let read_bytes = input.read(&mut buf)?;
43                if read_bytes > 0 {
44                    let s = String::from_utf8(buf);
45                    input_snd
46                        .send(s.unwrap_or_else(|_| "[ERROR] Requires UTF-8 Input".into()))
47                        .unwrap();
48                }
49                drop(input);
50                sleep(Duration::from_millis(10));
51            }
52
53            Ok(())
54        });
55    })
56    .unwrap();
57
58    input_rec
59}