use crate::{error::Error, tcp::ExternalEditorApi, Value};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::{__private::ser::FlatMapSerializer, ser::SerializeMap};
use std::io::{self};
#[derive(Debug)]
pub enum Message {
MessageGetScripts(MessageGetScripts),
MessageReload(MessageReload),
MessageCustomMessage(MessageCustomMessage),
MessageExecute(MessageExecute),
}
impl Serialize for Message {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = serializer.serialize_map(None)?;
let id_ = &match self {
Message::MessageGetScripts(_) => 0,
Message::MessageReload(_) => 1,
Message::MessageCustomMessage(_) => 2,
Message::MessageExecute(_) => 3,
};
s.serialize_entry("messageID", &id_)?;
match self {
Message::MessageGetScripts(t) => t.serialize(FlatMapSerializer(&mut s))?,
Message::MessageReload(t) => t.serialize(FlatMapSerializer(&mut s))?,
Message::MessageCustomMessage(t) => t.serialize(FlatMapSerializer(&mut s))?,
Message::MessageExecute(t) => t.serialize(FlatMapSerializer(&mut s))?,
}
s.end()
}
}
#[derive(Serialize, Debug)]
pub struct MessageGetScripts {}
impl TryFrom<Message> for MessageGetScripts {
type Error = Error;
fn try_from(message: Message) -> Result<Self, Self::Error> {
match message {
Message::MessageGetScripts(message) => Ok(message),
other => Err(Error::MessageError(other)),
}
}
}
impl MessageGetScripts {
pub fn new() -> Self {
Self {}
}
pub fn as_message(self) -> Message {
Message::MessageGetScripts(self)
}
}
#[derive(Serialize, Debug)]
pub struct MessageReload {
#[serde(rename = "scriptStates")]
pub script_states: Value,
}
impl TryFrom<Message> for MessageReload {
type Error = Error;
fn try_from(message: Message) -> Result<Self, Self::Error> {
match message {
Message::MessageReload(message) => Ok(message),
other => Err(Error::MessageError(other)),
}
}
}
impl MessageReload {
pub fn new(script_states: Value) -> Self {
Self { script_states }
}
pub fn as_message(self) -> Message {
Message::MessageReload(self)
}
}
#[derive(Serialize, Debug)]
pub struct MessageCustomMessage {
#[serde(rename = "customMessage")]
pub custom_message: Value,
}
impl TryFrom<Message> for MessageCustomMessage {
type Error = Error;
fn try_from(message: Message) -> Result<Self, Self::Error> {
match message {
Message::MessageCustomMessage(message) => Ok(message),
other => Err(Error::MessageError(other)),
}
}
}
impl MessageCustomMessage {
pub fn new(custom_message: Value) -> Self {
Self { custom_message }
}
pub fn as_message(self) -> Message {
Message::MessageCustomMessage(self)
}
}
#[derive(Serialize, Debug)]
pub struct MessageExecute {
#[serde(rename = "returnID")]
pub return_id: u64,
#[serde(rename = "guid")]
pub guid: String,
#[serde(rename = "script")]
pub script: String,
}
impl TryFrom<Message> for MessageExecute {
type Error = Error;
fn try_from(message: Message) -> Result<Self, Self::Error> {
match message {
Message::MessageExecute(message) => Ok(message),
other => Err(Error::MessageError(other)),
}
}
}
impl MessageExecute {
pub fn new(script: String) -> Self {
Self {
return_id: 5,
guid: String::from("-1"),
script,
}
}
pub fn new_object(script: String, guid: String) -> Self {
Self {
return_id: 5,
guid,
script,
}
}
pub fn as_message(self) -> Message {
Message::MessageExecute(self)
}
}
#[derive(Debug)]
pub enum Answer {
AnswerNewObject(AnswerNewObject),
AnswerReload(AnswerReload),
AnswerPrint(AnswerPrint),
AnswerError(AnswerError),
AnswerCustomMessage(AnswerCustomMessage),
AnswerReturn(AnswerReturn),
AnswerGameSaved(AnswerGameSaved),
AnswerObjectCreated(AnswerObjectCreated),
}
impl<'de> serde::Deserialize<'de> for Answer {
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let value = Value::deserialize(d)?;
Ok(
match value.get("messageID").and_then(Value::as_u64).unwrap() {
0 => Answer::AnswerNewObject(AnswerNewObject::deserialize(value).unwrap()),
1 => Answer::AnswerReload(AnswerReload::deserialize(value).unwrap()),
2 => Answer::AnswerPrint(AnswerPrint::deserialize(value).unwrap()),
3 => Answer::AnswerError(AnswerError::deserialize(value).unwrap()),
4 => Answer::AnswerCustomMessage(AnswerCustomMessage::deserialize(value).unwrap()),
5 => Answer::AnswerReturn(AnswerReturn::deserialize(value).unwrap()),
6 => Answer::AnswerGameSaved(AnswerGameSaved::deserialize(value).unwrap()),
7 => Answer::AnswerObjectCreated(AnswerObjectCreated::deserialize(value).unwrap()),
id_ => panic!("unsupported id {:?}", id_),
},
)
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerNewObject {
#[serde(rename = "scriptStates")]
pub script_states: Value,
}
impl TryFrom<Answer> for AnswerNewObject {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerNewObject(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerReload {
#[serde(rename = "savePath")]
pub save_path: String,
#[serde(rename = "scriptStates")]
pub script_states: Value,
}
impl TryFrom<Answer> for AnswerReload {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerReload(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerPrint {
#[serde(rename = "message")]
pub message: String,
}
impl TryFrom<Answer> for AnswerPrint {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerPrint(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerError {
#[serde(rename = "error")]
pub error: String,
#[serde(rename = "guid")]
pub guid: String,
#[serde(rename = "errorMessagePrefix")]
pub error_message_prefix: String,
}
impl TryFrom<Answer> for AnswerError {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerError(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerCustomMessage {
#[serde(rename = "customMessage")]
pub custom_message: Value,
}
impl TryFrom<Answer> for AnswerCustomMessage {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerCustomMessage(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerReturn {
#[serde(rename = "returnID")]
pub return_id: u64,
#[serde(
rename = "returnValue",
deserialize_with = "deserialize_json_string",
default
)]
pub return_value: Value,
}
impl TryFrom<Answer> for AnswerReturn {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerReturn(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
fn deserialize_json_string<'de, D>(deserializer: D) -> Result<Value, D::Error>
where
D: Deserializer<'de>,
{
match Option::deserialize(deserializer)? {
Some(val) => match val {
Value::String(val) => Ok(serde_json::from_str(&val).unwrap_or(Value::String(val))),
other => Ok(other),
},
None => Ok(Value::Null),
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerGameSaved {}
impl TryFrom<Answer> for AnswerGameSaved {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerGameSaved(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
#[derive(Deserialize, Debug)]
pub struct AnswerObjectCreated {
#[serde(rename = "guid")]
pub guid: String,
}
impl TryFrom<Answer> for AnswerObjectCreated {
type Error = Error;
fn try_from(answer: Answer) -> Result<Self, Self::Error> {
match answer {
Answer::AnswerObjectCreated(message) => Ok(message),
other => Err(Error::AnswerError(other)),
}
}
}
impl ExternalEditorApi {
pub fn get_scripts(&self) -> io::Result<AnswerReload> {
self.send(MessageGetScripts::new().as_message())?;
Ok(self.wait())
}
pub fn reload(&self, script_states: Value) -> io::Result<AnswerReload> {
self.send(MessageReload::new(script_states).as_message())?;
Ok(self.wait())
}
pub fn custom_message(&self, message: Value) -> io::Result<()> {
self.send(MessageCustomMessage::new(message).as_message())?;
Ok(())
}
pub fn execute(&self, script: String) -> io::Result<AnswerReturn> {
self.send(MessageExecute::new(script).as_message())?;
Ok(self.wait())
}
pub fn execute_on_object(&self, script: String, guid: String) -> io::Result<AnswerReturn> {
self.send(MessageExecute::new_object(script, guid).as_message())?;
Ok(self.wait())
}
}