custom_serialization/
custom-serialization.rs

1use std::borrow::Cow;
2use std::fs;
3use std::io;
4use std::path::{Path, PathBuf};
5
6use serde::{de::Deserializer, de::Error, ser::Serializer};
7use serde::{Deserialize, Serialize};
8
9#[derive(Serialize, Deserialize)]
10struct MyBytesHelper<'a> {
11    path: Cow<'a, Path>,
12    bytes: Cow<'a, [u8]>,
13}
14
15#[derive(Clone, PartialEq, Debug)]
16struct MyBytes {
17    path: PathBuf,
18    bytes: Vec<u8>,
19}
20
21impl MyBytes {
22    pub fn open<P: AsRef<Path>>(p: P) -> io::Result<MyBytes> {
23        println!("opening file in {}", std::process::id());
24        let path = p.as_ref().to_path_buf();
25        Ok(MyBytes {
26            bytes: fs::read(&path)?,
27            path,
28        })
29    }
30}
31
32impl Serialize for MyBytes {
33    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
34    where
35        S: Serializer,
36    {
37        if procspawn::serde::in_ipc_mode() {
38            println!("serialize in ipc mode");
39            self.path.serialize(serializer)
40        } else {
41            println!("serialize in normal mode");
42            MyBytesHelper {
43                path: Cow::Borrowed(&self.path),
44                bytes: Cow::Borrowed(&self.bytes),
45            }
46            .serialize(serializer)
47        }
48    }
49}
50
51impl<'de> Deserialize<'de> for MyBytes {
52    fn deserialize<D>(deserializer: D) -> Result<MyBytes, D::Error>
53    where
54        D: Deserializer<'de>,
55    {
56        if procspawn::serde::in_ipc_mode() {
57            println!("deserialize in ipc mode");
58            let path = PathBuf::deserialize(deserializer)?;
59            MyBytes::open(path).map_err(D::Error::custom)
60        } else {
61            println!("deserialize in normal mode");
62            let helper = MyBytesHelper::deserialize(deserializer)?;
63            Ok(MyBytes {
64                path: helper.path.into_owned(),
65                bytes: helper.bytes.into_owned(),
66            })
67        }
68    }
69}
70
71fn main() {
72    procspawn::init();
73
74    let bytes = MyBytes::open("Cargo.toml").unwrap();
75
76    let bytes_two = procspawn::spawn!((bytes.clone() => bytes) || {
77        println!("length: {}", bytes.bytes.len());
78        bytes
79    })
80    .join()
81    .unwrap();
82
83    assert_eq!(bytes, bytes_two);
84}