dprint_core/communication/
message.rs1use std::io::ErrorKind;
2use std::io::Write;
3
4use crate::communication::MessageWriter;
5
6pub trait Message: std::fmt::Debug + Send + Sync + 'static {
7 fn write<TWrite: Write + Unpin>(&self, writer: &mut MessageWriter<TWrite>) -> std::io::Result<()>;
8}
9
10struct SingleThreadMessageWriterOptions<TWrite: Write + Unpin> {
11 pub writer: MessageWriter<TWrite>,
12 pub panic_on_write_fail: bool,
13}
14
15pub struct SingleThreadMessageWriter<TMessage: Message> {
17 tx: crossbeam_channel::Sender<TMessage>,
18}
19
20impl<TMessage: Message> SingleThreadMessageWriter<TMessage> {
21 pub fn for_stdout<TWrite: Write + Unpin + Send + 'static>(writer: MessageWriter<TWrite>) -> Self {
22 Self::new(SingleThreadMessageWriterOptions {
23 writer,
24 panic_on_write_fail: true,
25 })
26 }
27
28 pub fn for_stdin<TWrite: Write + Unpin + Send + 'static>(writer: MessageWriter<TWrite>) -> Self {
29 Self::new(SingleThreadMessageWriterOptions {
30 writer,
31 panic_on_write_fail: false,
32 })
33 }
34
35 fn new<TWrite: Write + Unpin + Send + 'static>(mut opts: SingleThreadMessageWriterOptions<TWrite>) -> Self {
36 let (tx, rx) = crossbeam_channel::unbounded::<TMessage>();
37
38 crate::async_runtime::spawn_blocking({
40 move || {
41 while let Ok(result) = rx.recv() {
42 if let Err(err) = result.write(&mut opts.writer) {
43 if opts.panic_on_write_fail {
44 panic!("{:#}", err);
45 } else {
46 break;
47 }
48 }
49 }
50 }
51 });
52
53 Self { tx }
54 }
55
56 pub fn send(&self, message: TMessage) -> std::io::Result<()> {
57 self.tx.send(message).map_err(|err| std::io::Error::new(ErrorKind::BrokenPipe, err))
58 }
59}