1mod errors;
2
3pub use errors::DecodeError;
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Serialize, Deserialize)]
8pub enum Message {
9 Manifest(Manifest),
10 NeedFiles(Vec<String>),
11 FileData { path: String, contents: Vec<u8> },
12 SyncDone,
13 SyncAck,
14 BuildStdout(Vec<u8>),
15 BuildStderr(Vec<u8>),
16 BuildFinished { exit_code: u8 },
17 SlotsBusy,
21 Probe {
33 fingerprint: [u8; 32],
34 request: BuildRequest,
35 },
36 ProbeAccepted,
37 ProbeMiss,
38}
39
40impl Message {
41 pub fn kind(&self) -> &'static str {
44 match self {
45 Message::Manifest(_) => "Manifest",
46 Message::NeedFiles(_) => "NeedFiles",
47 Message::FileData { .. } => "FileData",
48 Message::SyncDone => "SyncDone",
49 Message::SyncAck => "SyncAck",
50 Message::BuildStdout(_) => "BuildStdout",
51 Message::BuildStderr(_) => "BuildStderr",
52 Message::BuildFinished { .. } => "BuildFinished",
53 Message::SlotsBusy => "SlotsBusy",
54 Message::Probe { .. } => "Probe",
55 Message::ProbeAccepted => "ProbeAccepted",
56 Message::ProbeMiss => "ProbeMiss",
57 }
58 }
59}
60
61#[derive(Debug, Serialize, Deserialize)]
62pub struct Manifest {
63 pub team: String,
64 pub scope: String,
65 pub files_gz: Vec<u8>,
67}
68
69impl Manifest {
70 pub fn encode_files(files: &[FileEntry]) -> Vec<u8> {
71 use flate2::{Compression, write::GzEncoder};
72 use std::io::Write;
73 let raw = bincode::serialize(files).unwrap();
74 let mut enc = GzEncoder::new(Vec::new(), Compression::default());
75 enc.write_all(&raw).unwrap();
76 enc.finish().unwrap()
77 }
78
79 pub fn decode_files(&self) -> Result<Vec<FileEntry>, DecodeError> {
80 use flate2::read::GzDecoder;
81 use std::io::Read;
82 let mut dec = GzDecoder::new(&self.files_gz[..]);
83 let mut raw = Vec::new();
84 dec.read_to_end(&mut raw).map_err(|e| DecodeError(Box::new(bincode::ErrorKind::Custom(e.to_string()))))?;
85 bincode::deserialize(&raw).map_err(DecodeError)
86 }
87}
88
89#[derive(Debug, Serialize, Deserialize)]
90pub struct FileEntry {
91 pub path: String,
92 pub hash: [u8; 32],
93}
94
95#[derive(Debug, Serialize, Deserialize)]
97#[repr(u8)]
98pub enum Arch {
99 X86_64 = 0,
100 Aarch64 = 1,
101}
102
103#[derive(Debug, Serialize, Deserialize)]
105#[repr(u8)]
106pub enum Os {
107 Windows = 0,
108 Linux = 1,
109 Mac = 2,
110}
111
112#[derive(Debug, Serialize, Deserialize)]
114#[repr(u8)]
115pub enum Abi {
116 Gnu = 0,
117 Musl = 1,
118 Msvc = 2,
119}
120
121#[derive(Debug, Serialize, Deserialize)]
122pub struct PlatformTriple {
123 pub arch: Arch,
124 pub os: Os,
125 pub abi: Abi,
126}
127
128impl PlatformTriple {
129 pub fn as_cargo_target_string(&self) -> String {
130 match (&self.arch, &self.os, &self.abi) {
131 (Arch::X86_64, Os::Linux, Abi::Gnu) => "x86_64-unknown-linux-gnu",
132 (Arch::X86_64, Os::Linux, Abi::Musl) => "x86_64-unknown-linux-musl",
133 (Arch::Aarch64, Os::Linux, Abi::Gnu) => "aarch64-unknown-linux-gnu",
134 (Arch::Aarch64, Os::Linux, Abi::Musl) => "aarch64-unknown-linux-musl",
135 (Arch::X86_64, Os::Windows, Abi::Msvc) => "x86_64-pc-windows-msvc",
136 (Arch::X86_64, Os::Windows, Abi::Gnu) => "x86_64-pc-windows-gnu",
137 (Arch::Aarch64, Os::Windows, Abi::Msvc) => "aarch64-pc-windows-msvc",
138 (Arch::X86_64, Os::Mac, _) => "x86_64-apple-darwin",
139 (Arch::Aarch64, Os::Mac, _) => "aarch64-apple-darwin",
140 _ => unimplemented!(),
141 }
142 .to_string()
143 }
144}
145
146#[derive(Debug, Serialize, Deserialize)]
147pub struct BuildRequest {
148 pub cargo_args: Vec<String>,
149 pub subdir: Option<String>,
150 pub host_platform: PlatformTriple,
151 pub team: String,
152 pub scope: String,
153}
154
155pub fn serialize(msg: &Message) -> Vec<u8> {
158 bincode::serialize(msg).unwrap()
159}
160
161pub fn deserialize(raw: &[u8]) -> Result<Message, DecodeError> {
163 bincode::deserialize(raw).map_err(DecodeError)
164}