1use std::collections::VecDeque;
2use std::sync::mpsc::{channel, Receiver, RecvError, Sender, TryRecvError};
3use std::thread;
4use url::Url;
5
6use languageserver_types::{Position, Range};
7
8pub type TaskId = usize;
9
10#[derive(Debug)]
12pub enum QueryRequest {
13 TypeAtPosition(TaskId, Url, Position),
14 RenameAtPosition(TaskId, Url, Position, String),
15 DefinitionAtPosition(TaskId, Url, Position),
16 ReferencesAtPosition(TaskId, Url, Position, bool),
17 OpenFile(Url, String),
18 EditFile(Url, Vec<(Range, String)>),
19 Initialize(TaskId),
20}
21impl QueryRequest {
22 pub fn is_mutation(&self) -> bool {
25 match self {
26 QueryRequest::OpenFile(..)
27 | QueryRequest::EditFile(..)
28 | QueryRequest::RenameAtPosition(..)
29 | QueryRequest::Initialize(..) => true,
30 QueryRequest::TypeAtPosition(..) => false,
31 QueryRequest::DefinitionAtPosition(..) => false,
32 QueryRequest::ReferencesAtPosition(..) => false,
33 }
34 }
35}
36
37pub enum LspResponse {
40 Type(TaskId, String),
41 Range(TaskId, Url, Range),
42 Ranges(TaskId, Vec<(Url, Range)>),
43 WorkspaceEdits(TaskId, Vec<(Url, Range, String)>),
44 Completions(TaskId, Vec<(String, String)>),
45 Initialized(TaskId),
46 Nothing(TaskId),
47 Diagnostics(Url, Vec<(Range, String)>),
48}
49
50pub trait Actor {
53 type InMessage: Send + Sync + 'static;
54
55 fn receive_messages(&mut self, messages: &mut VecDeque<Self::InMessage>);
73}
74
75pub struct ActorControl<MessageType: Send + Sync + 'static> {
76 pub channel: Sender<MessageType>,
77 pub join_handle: std::thread::JoinHandle<()>,
78}
79
80pub fn spawn_actor<T: Actor + Send + 'static>(mut actor: T) -> ActorControl<T::InMessage> {
81 let (actor_tx, actor_rx) = channel();
82 let mut message_queue = VecDeque::default();
83
84 let handle = thread::spawn(move || loop {
85 match push_all_pending(&actor_rx, &mut message_queue) {
86 Ok(()) => {
87 actor.receive_messages(&mut message_queue);
88 }
89 Err(error) => {
90 match error {
91 PushAllPendingError::Disconnected => {
92 eprintln!("Failure during top-level message receive");
93 }
94 }
95
96 break;
97 }
98 }
99 });
100
101 ActorControl {
102 channel: actor_tx,
103 join_handle: handle,
104 }
105}
106
107enum PushAllPendingError {
108 Disconnected,
109}
110
111fn push_all_pending<T>(rx: &Receiver<T>, vec: &mut VecDeque<T>) -> Result<(), PushAllPendingError> {
112 if vec.is_empty() {
115 match rx.recv() {
116 Ok(m) => vec.push_back(m),
117 Err(RecvError) => return Err(PushAllPendingError::Disconnected),
118 }
119 }
120
121 loop {
123 match rx.try_recv() {
124 Ok(m) => vec.push_back(m),
125 Err(TryRecvError::Empty) => break Ok(()),
126 Err(TryRecvError::Disconnected) => break Err(PushAllPendingError::Disconnected),
127 }
128 }
129}