1use serde::Serialize;
2
3use crate::js::value::JsValue;
4use crate::protocol::GET;
5
6pub trait UseInJsCode {
12 fn serialize_to(&self, buf: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
13}
14
15impl UseInJsCode for JsValue {
16 fn serialize_to(&self, buf: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17 let self_id = self.id;
18 write!(buf, "{GET}({self_id})").unwrap();
19 Ok(())
20 }
21}
22
23pub struct SerdeToJs<'a, T: ?Sized>(pub &'a T);
24
25impl<'a, T: Serialize + ?Sized> UseInJsCode for SerdeToJs<'a, T> {
26 fn serialize_to(&self, buf: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 struct WriteAdapter<'a, 'b>(&'a mut std::fmt::Formatter<'b>);
28 impl<'a, 'b> std::io::Write for WriteAdapter<'a, 'b> {
29 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
30 match self.0.write_str(unsafe {
31 std::str::from_utf8_unchecked(buf)
34 }) {
35 Ok(()) => Ok(buf.len()),
36 Err(std::fmt::Error) => Err(std::io::ErrorKind::Other.into()),
37 }
38 }
39 fn flush(&mut self) -> std::io::Result<()> {
40 Ok(())
41 }
42 }
43 match serde_json::to_writer(&mut WriteAdapter(buf), self.0) {
44 Ok(()) => Ok(()),
45 Err(_) => Err(std::fmt::Error),
46 }
47 }
48}
49
50pub(crate) struct UseInJsCodeWriter<'a, T: UseInJsCode + ?Sized>(pub &'a T);
51
52impl<'a, T: UseInJsCode + ?Sized> std::fmt::Display for UseInJsCodeWriter<'a, T> {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 self.0.serialize_to(f)
55 }
56}
57
58pub struct RawCodeImmediate<'a>(pub &'a str);
59impl<'a> UseInJsCode for RawCodeImmediate<'a> {
60 fn serialize_to(&self, buf: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 buf.write_str(self.0)
62 }
63}
64
65pub trait ToJs<JsType>
70where
71 Self: UseInJsCode,
72 JsType: ?Sized,
73{
74}
75
76impl<T: ?Sized> ToJs<T> for T where T: UseInJsCode {}