use futures::{future, Future};
use serde_json::Value;
use errors::ClientError;
use protocol;
use serde_json::{from_value, to_value};
use serde::Serialize;
pub type ClientResult<T> = Box<Future<Item = T, Error = ClientError>>;
#[derive(Clone)]
pub struct Client(pub protocol::Client);
fn get_edit_params<T: Serialize>(
view_id: &str,
method: &str,
params: Option<T>,
) -> Result<Value, ClientError> {
let params_value = if let Some(params) = params {
to_value(params)?
} else {
json!([])
};
Ok(json!({
"method": method,
"view_id": view_id,
"params": params_value,
}))
}
impl Client {
pub fn notify(&mut self, method: &str, params: Value) -> ClientResult<()> {
Box::new(
self.0
.notify(method, params)
.map_err(|_| ClientError::NotifyFailed),
)
}
pub fn request(&mut self, method: &str, params: Value) -> ClientResult<Value> {
Box::new(self.0.request(method, params).then(
|response| match response {
Ok(Ok(value)) => Ok(value),
Ok(Err(value)) => Err(ClientError::ErrorReturned(value)),
Err(_) => Err(ClientError::RequestFailed),
},
))
}
fn edit<T: Serialize>(
&mut self,
view_id: &str,
method: &str,
params: Option<T>,
) -> ClientResult<()> {
match get_edit_params(view_id, method, params) {
Ok(value) => self.notify("edit", value),
Err(e) => Box::new(future::err(e)),
}
}
pub fn scroll(&mut self, view_id: &str, first_line: u64, last_line: u64) -> ClientResult<()> {
self.edit(view_id, "scroll", Some(json!([first_line, last_line])))
}
pub fn left(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "move_left", None as Option<Value>)
}
pub fn left_sel(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(
view_id,
"move_left_and_modify_selection",
None as Option<Value>,
)
}
pub fn right(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "move_right", None as Option<Value>)
}
pub fn right_sel(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(
view_id,
"move_right_and_modify_selection",
None as Option<Value>,
)
}
pub fn up(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "move_up", None as Option<Value>)
}
pub fn up_sel(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(
view_id,
"move_up_and_modify_selection",
None as Option<Value>,
)
}
pub fn down(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "move_down", None as Option<Value>)
}
pub fn down_sel(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(
view_id,
"move_down_and_modify_selection",
None as Option<Value>,
)
}
pub fn del(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "delete_backward", None as Option<Value>)
}
pub fn page_up(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "page_up", None as Option<Value>)
}
pub fn page_up_sel(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(
view_id,
"page_up_and_modify_selection",
None as Option<Value>,
)
}
pub fn page_down(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "page_down", None as Option<Value>)
}
pub fn page_down_sel(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(
view_id,
"page_down_and_modify_selection",
None as Option<Value>,
)
}
pub fn insert_newline(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "insert_newline", None as Option<Value>)
}
pub fn f1(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "debug_rewrap", None as Option<Value>)
}
pub fn f2(&mut self, view_id: &str) -> ClientResult<()> {
self.edit(view_id, "debug_test_fg_spans", None as Option<Value>)
}
pub fn char(&mut self, view_id: &str, ch: char) -> ClientResult<()> {
self.edit(view_id, "insert", Some(json!({ "chars": ch })))
}
pub fn click(&mut self, view_id: &str, line: u64, column: u64) -> ClientResult<()> {
self.edit(view_id, "click", Some(json!([line, column, 0, 1])))
}
pub fn drag(&mut self, view_id: &str, line: u64, column: u64) -> ClientResult<()> {
self.edit(view_id, "drag", Some(json!([line, column, 0])))
}
pub fn new_view(&mut self, file_path: Option<String>) -> ClientResult<String> {
let params = if let Some(file_path) = file_path {
json!({ "file_path": file_path })
} else {
json!({})
};
let result = self.request("new_view", params)
.and_then(|result| from_value::<String>(result).map_err(From::from));
Box::new(result)
}
pub fn close_view(&mut self, view_id: &str) -> ClientResult<()> {
self.notify("close_view", json!({ "view_id": view_id }))
}
pub fn save(&mut self, view_id: &str, file_path: &str) -> ClientResult<()> {
let params = json!({"view_id": view_id, "file_path": file_path});
Box::new(self.request("save", params).and_then(|_| Ok(())))
}
}