1 use serde::ser::{SerializeSeq, SerializeStruct, SerializeTupleStruct, Serializer};
2 use serde::Serialize;
3 use serde_starlark::{FunctionCall, MULTILINE, ONELINE};
4
5 use super::{
6 Data, ExportsFiles, License, Load, Package, PackageInfo, RustBinary, RustLibrary, RustProcMacro,
7 };
8
9 // For structs that contain #[serde(flatten)], a quirk of how Serde processes
10 // that attribute is that they get serialized as a map, not struct. In Starlark
11 // unlike in JSON, maps and structs are differently serialized, so we need to
12 // help fill in the function name or else we'd get a Starlark map instead.
rust_proc_macro<S>(rule: &RustProcMacro, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,13 pub(crate) fn rust_proc_macro<S>(rule: &RustProcMacro, serializer: S) -> Result<S::Ok, S::Error>
14 where
15 S: Serializer,
16 {
17 FunctionCall::new("rust_proc_macro", rule).serialize(serializer)
18 }
19
rust_library<S>(rule: &RustLibrary, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,20 pub(crate) fn rust_library<S>(rule: &RustLibrary, serializer: S) -> Result<S::Ok, S::Error>
21 where
22 S: Serializer,
23 {
24 FunctionCall::new("rust_library", rule).serialize(serializer)
25 }
26
rust_binary<S>(rule: &RustBinary, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,27 pub(crate) fn rust_binary<S>(rule: &RustBinary, serializer: S) -> Result<S::Ok, S::Error>
28 where
29 S: Serializer,
30 {
31 FunctionCall::new("rust_binary", rule).serialize(serializer)
32 }
33
34 // Serialize an array with each element on its own line, even if there is just a
35 // single element which serde_starlark would ordinarily place on the same line
36 // as the array brackets.
37 pub(crate) struct MultilineArray<'a, A>(pub(crate) &'a A);
38
39 impl<'a, A, T> Serialize for MultilineArray<'a, A>
40 where
41 &'a A: IntoIterator<Item = &'a T>,
42 T: Serialize + 'a,
43 {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,44 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
45 where
46 S: Serializer,
47 {
48 let mut array = serializer.serialize_seq(Some(serde_starlark::MULTILINE))?;
49 for element in self.0 {
50 array.serialize_element(element)?;
51 }
52 array.end()
53 }
54 }
55
56 impl Serialize for Load {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,57 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58 where
59 S: Serializer,
60 {
61 let line = if self.items.len() > 1 {
62 MULTILINE
63 } else {
64 ONELINE
65 };
66 let mut call = serializer.serialize_tuple_struct("load", line)?;
67 call.serialize_field(&self.bzl)?;
68 for item in &self.items {
69 call.serialize_field(item)?;
70 }
71 call.end()
72 }
73 }
74
75 impl Serialize for Package {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,76 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
77 where
78 S: Serializer,
79 {
80 let has_metadata = !self.default_package_metadata.is_empty();
81 let mut call = serializer
82 .serialize_struct("package", if has_metadata { MULTILINE } else { ONELINE })?;
83 if has_metadata {
84 call.serialize_field("default_package_metadata", &self.default_package_metadata)?;
85 }
86 call.serialize_field("default_visibility", &self.default_visibility)?;
87 call.end()
88 }
89 }
90
91 impl Serialize for PackageInfo {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: Serializer,
95 {
96 let mut call = serializer.serialize_struct("package_info", MULTILINE)?;
97 call.serialize_field("name", &self.name)?;
98 call.serialize_field("package_name", &self.package_name)?;
99 call.serialize_field("package_version", &self.package_version)?;
100 call.serialize_field("package_url", &self.package_url)?;
101 call.end()
102 }
103 }
104
105 impl Serialize for License {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,106 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107 where
108 S: Serializer,
109 {
110 let mut call = serializer.serialize_struct("license", MULTILINE)?;
111 call.serialize_field("name", &self.name)?;
112 call.serialize_field("license_kinds", &self.license_kinds)?;
113 if !self.license_text.is_empty() {
114 call.serialize_field("license_text", &self.license_text)?;
115 }
116 call.end()
117 }
118 }
119
120 impl Serialize for ExportsFiles {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,121 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
122 where
123 S: Serializer,
124 {
125 let mut call = serializer.serialize_tuple_struct("exports_files", MULTILINE)?;
126 call.serialize_field(&FunctionCall::new("+", (&self.paths, &self.globs)))?;
127 call.end()
128 }
129 }
130
131 impl Data {
is_empty(&self) -> bool132 pub(crate) fn is_empty(&self) -> bool {
133 self.glob.has_any_include() && self.select.is_empty()
134 }
135 }
136
137 impl Serialize for Data {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,138 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
139 where
140 S: Serializer,
141 {
142 let mut plus = serializer.serialize_tuple_struct("+", MULTILINE)?;
143 if !self.glob.has_any_include() {
144 plus.serialize_field(&self.glob)?;
145 }
146 if !self.select.is_empty() || self.glob.has_any_include() {
147 plus.serialize_field(&self.select)?;
148 }
149 plus.end()
150 }
151 }
152