1use std::{borrow::Cow, fmt};
2
3use serde::{ser, Serialize};
4
5type Result<T> = std::result::Result<T, LuaSerializerError>;
6
7pub(crate) fn to_expression<T>(value: &T) -> Result<Expression>
9where
10 T: Serialize,
11{
12 let mut serializer = Serializer {
13 output: Expression::nil(),
14 operation: Vec::new(),
15 expression_stack: Vec::new(),
16 };
17 value.serialize(&mut serializer)?;
18 Ok(serializer.output)
19}
20
21#[derive(Debug)]
22pub(crate) struct LuaSerializerError {
23 message: Cow<'static, str>,
24 is_internal: bool,
25}
26
27impl LuaSerializerError {
28 pub(crate) fn new(message: impl Into<Cow<'static, str>>) -> Self {
29 Self {
30 message: message.into(),
31 is_internal: false,
32 }
33 }
34
35 pub(crate) fn internal(message: impl Into<Cow<'static, str>>) -> Self {
36 Self {
37 message: message.into(),
38 is_internal: true,
39 }
40 }
41}
42
43impl ser::Error for LuaSerializerError {
44 fn custom<T: fmt::Display>(msg: T) -> Self {
45 LuaSerializerError::new(msg.to_string())
46 }
47}
48
49impl fmt::Display for LuaSerializerError {
50 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
51 if self.is_internal {
52 formatter.write_str(&self.message)
53 } else {
54 write!(formatter, "{} [internal]", self.message)
55 }
56 }
57}
58
59impl std::error::Error for LuaSerializerError {}
60
61use crate::{
62 nodes::{
63 DecimalNumber, Expression, FieldExpression, FunctionCall, HexNumber, Identifier,
64 StringExpression, TableEntry, TableExpression, TableFieldEntry, TableIndexEntry,
65 TupleArguments,
66 },
67 process::utils::is_valid_identifier,
68};
69
70enum SerializeOperation {
71 Table(Vec<TableEntry>),
72 TableEntryKey,
73 TableEntryValue,
74}
75
76struct Serializer {
77 output: Expression,
78 operation: Vec<SerializeOperation>,
79 expression_stack: Vec<Expression>,
80}
81
82impl Serializer {
83 fn process(&mut self, expression: Expression) -> Result<()> {
84 if let Some(mut operation) = self.operation.pop() {
85 let keep = match &mut operation {
86 SerializeOperation::Table(entries) => {
87 entries.push(TableEntry::Value(expression));
88 true
89 }
90 SerializeOperation::TableEntryKey => {
91 self.expression_stack.push(expression);
92 false
93 }
94 SerializeOperation::TableEntryValue => {
95 self.complete_table_entry(expression)?;
96 false
97 }
98 };
99
100 if keep {
101 self.operation.push(operation);
102 }
103 } else {
104 self.output = expression;
105 }
106 Ok(())
107 }
108
109 fn complete_table_entry(&mut self, entry_value: Expression) -> Result<()> {
113 let key = self.expression_stack.pop().ok_or_else(|| {
114 LuaSerializerError::internal("key expression expected to build table expression")
115 })?;
116
117 if let Some(last_operation) = self.operation.last_mut() {
118 match last_operation {
119 SerializeOperation::Table(entries) => {
120 if let Expression::String(string) = key {
121 if is_valid_identifier(string.get_value()) {
122 entries.push(
123 TableFieldEntry::new(string.into_value(), entry_value).into(),
124 );
125 } else {
126 entries.push(TableIndexEntry::new(string, entry_value).into());
127 }
128 } else {
129 entries.push(TableIndexEntry::new(key, entry_value).into());
130 }
131 Ok(())
132 }
133 SerializeOperation::TableEntryKey => Err(LuaSerializerError::internal(
134 "unable to push key-value pair with a table key operation",
135 )),
136 SerializeOperation::TableEntryValue => Err(LuaSerializerError::internal(
137 "unable to push key-value pair with a table value operation",
138 )),
139 }
140 } else {
141 Err(LuaSerializerError::internal(
142 "missing table operation to push key-value pair",
143 ))
144 }
145 }
146
147 fn begin_table(&mut self, len: Option<usize>) {
148 let mut sequence = Vec::<TableEntry>::new();
149 if let Some(len) = len {
150 sequence.reserve_exact(len);
151 }
152 self.operation.push(SerializeOperation::Table(sequence));
153 }
154
155 fn close_table(&mut self) -> Result<()> {
156 if let Some(operation) = self.operation.pop() {
157 match operation {
158 SerializeOperation::Table(entries) => {
159 self.process(TableExpression::new(entries).into())
160 }
161 SerializeOperation::TableEntryValue => Err(LuaSerializerError::internal(
162 "unable to complete table with a table value operation",
163 )),
164 SerializeOperation::TableEntryKey => Err(LuaSerializerError::internal(
165 "unable to complete table with a table key operation",
166 )),
167 }
168 } else {
169 Err(LuaSerializerError::internal(
170 "missing table operation to complete table expression",
171 ))
172 }
173 }
174
175 fn begin_table_entry_key(&mut self) {
176 self.operation.push(SerializeOperation::TableEntryKey);
177 }
178
179 fn begin_table_entry_value(&mut self) {
180 self.operation.push(SerializeOperation::TableEntryValue);
181 }
182}
183
184impl<'a> ser::Serializer for &'a mut Serializer {
185 type Ok = ();
192
193 type Error = LuaSerializerError;
195
196 type SerializeSeq = Self;
201 type SerializeTuple = Self;
202 type SerializeTupleStruct = Self;
203 type SerializeTupleVariant = Self;
204 type SerializeMap = Self;
205 type SerializeStruct = Self;
206 type SerializeStructVariant = Self;
207
208 fn serialize_bool(self, v: bool) -> Result<()> {
209 self.process(v.into())
210 }
211
212 fn serialize_i8(self, v: i8) -> Result<()> {
213 self.serialize_i64(i64::from(v))
214 }
215
216 fn serialize_i16(self, v: i16) -> Result<()> {
217 self.serialize_i64(i64::from(v))
218 }
219
220 fn serialize_i32(self, v: i32) -> Result<()> {
221 self.serialize_i64(i64::from(v))
222 }
223
224 fn serialize_i64(self, v: i64) -> Result<()> {
225 self.process(DecimalNumber::new(v as f64).into())
226 }
227
228 fn serialize_u8(self, v: u8) -> Result<()> {
229 self.serialize_u64(u64::from(v))
230 }
231
232 fn serialize_u16(self, v: u16) -> Result<()> {
233 self.serialize_u64(u64::from(v))
234 }
235
236 fn serialize_u32(self, v: u32) -> Result<()> {
237 self.serialize_u64(u64::from(v))
238 }
239
240 fn serialize_u64(self, v: u64) -> Result<()> {
241 self.process(DecimalNumber::new(v as f64).into())
242 }
243
244 fn serialize_f32(self, v: f32) -> Result<()> {
245 self.serialize_f64(f64::from(v))
246 }
247
248 fn serialize_f64(self, v: f64) -> Result<()> {
249 self.process(DecimalNumber::new(v).into())
250 }
251
252 fn serialize_char(self, v: char) -> Result<()> {
253 self.serialize_str(&v.to_string())
254 }
255
256 fn serialize_str(self, v: &str) -> Result<()> {
257 self.process(StringExpression::from_value(v).into())
258 }
259
260 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
264 let arguments = v.iter().fold(TupleArguments::default(), |arguments, byte| {
265 arguments.with_argument(HexNumber::new(*byte as u64, false))
266 });
267 self.process(
268 FunctionCall::new(
269 FieldExpression::new(Identifier::new("string"), "char").into(),
270 arguments.into(),
271 None,
272 )
273 .into(),
274 )
275 }
276
277 fn serialize_none(self) -> Result<()> {
278 self.process(Expression::nil())
279 }
280
281 fn serialize_some<T>(self, value: &T) -> Result<()>
282 where
283 T: ?Sized + Serialize,
284 {
285 value.serialize(self)
286 }
287
288 fn serialize_unit(self) -> Result<()> {
290 self.process(Expression::nil())
291 }
292
293 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
295 self.serialize_unit()
296 }
297
298 fn serialize_unit_variant(
303 self,
304 _name: &'static str,
305 _variant_index: u32,
306 variant: &'static str,
307 ) -> Result<()> {
308 self.serialize_str(variant)
309 }
310
311 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
314 where
315 T: ?Sized + Serialize,
316 {
317 value.serialize(self)
318 }
319
320 fn serialize_newtype_variant<T>(
326 self,
327 _name: &'static str,
328 _variant_index: u32,
329 variant: &'static str,
330 value: &T,
331 ) -> Result<()>
332 where
333 T: ?Sized + Serialize,
334 {
335 self.begin_table(Some(1));
336 self.begin_table_entry_key();
337 variant.serialize(&mut *self)?;
338 self.begin_table_entry_value();
339 value.serialize(&mut *self)?;
340 self.close_table()
341 }
342
343 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
353 self.begin_table(len);
354 Ok(self)
355 }
356
357 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
359 self.serialize_seq(Some(len))
360 }
361
362 fn serialize_tuple_struct(
364 self,
365 _name: &'static str,
366 len: usize,
367 ) -> Result<Self::SerializeTupleStruct> {
368 self.serialize_seq(Some(len))
369 }
370
371 fn serialize_tuple_variant(
374 self,
375 _name: &'static str,
376 _variant_index: u32,
377 variant: &'static str,
378 len: usize,
379 ) -> Result<Self::SerializeTupleVariant> {
380 self.begin_table(Some(1));
381 self.begin_table_entry_key();
382 variant.serialize(&mut *self)?;
383 self.begin_table_entry_value();
384 self.begin_table(Some(len));
385 Ok(self)
386 }
387
388 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
390 self.begin_table(len);
391 Ok(self)
392 }
393
394 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
400 self.serialize_map(Some(len))
401 }
402
403 fn serialize_struct_variant(
406 self,
407 _name: &'static str,
408 _variant_index: u32,
409 variant: &'static str,
410 len: usize,
411 ) -> Result<Self::SerializeStructVariant> {
412 self.begin_table(Some(1));
413 self.begin_table_entry_key();
414 variant.serialize(&mut *self)?;
415 self.begin_table_entry_value();
416 self.begin_table(Some(len));
417 Ok(self)
418 }
419}
420
421impl<'a> ser::SerializeSeq for &'a mut Serializer {
429 type Ok = ();
431 type Error = LuaSerializerError;
433
434 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
436 where
437 T: ?Sized + Serialize,
438 {
439 value.serialize(&mut **self)
440 }
441
442 fn end(self) -> Result<()> {
444 self.close_table()
445 }
446}
447
448impl<'a> ser::SerializeTuple for &'a mut Serializer {
450 type Ok = ();
451 type Error = LuaSerializerError;
452
453 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
454 where
455 T: ?Sized + Serialize,
456 {
457 value.serialize(&mut **self)
458 }
459
460 fn end(self) -> Result<()> {
461 self.close_table()
462 }
463}
464
465impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
467 type Ok = ();
468 type Error = LuaSerializerError;
469
470 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
471 where
472 T: ?Sized + Serialize,
473 {
474 value.serialize(&mut **self)
475 }
476
477 fn end(self) -> Result<()> {
478 self.close_table()
479 }
480}
481
482impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
487 type Ok = ();
488 type Error = LuaSerializerError;
489
490 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
491 where
492 T: ?Sized + Serialize,
493 {
494 value.serialize(&mut **self)
495 }
496
497 fn end(self) -> Result<()> {
498 self.close_table()?;
499 self.close_table()
500 }
501}
502
503impl<'a> ser::SerializeMap for &'a mut Serializer {
511 type Ok = ();
512 type Error = LuaSerializerError;
513
514 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
516 where
517 T: ?Sized + Serialize,
518 {
519 self.begin_table_entry_key();
520 key.serialize(&mut **self)
521 }
522
523 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
524 where
525 T: ?Sized + Serialize,
526 {
527 self.begin_table_entry_value();
528 value.serialize(&mut **self)
529 }
530
531 fn end(self) -> Result<()> {
532 self.close_table()
533 }
534}
535
536impl<'a> ser::SerializeStruct for &'a mut Serializer {
539 type Ok = ();
540 type Error = LuaSerializerError;
541
542 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
543 where
544 T: ?Sized + Serialize,
545 {
546 self.begin_table_entry_key();
547 key.serialize(&mut **self)?;
548 self.begin_table_entry_value();
549 value.serialize(&mut **self)
550 }
551
552 fn end(self) -> Result<()> {
553 self.close_table()
554 }
555}
556
557impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
560 type Ok = ();
561 type Error = LuaSerializerError;
562
563 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
564 where
565 T: ?Sized + Serialize,
566 {
567 self.begin_table_entry_key();
568 key.serialize(&mut **self)?;
569 self.begin_table_entry_value();
570 value.serialize(&mut **self)
571 }
572
573 fn end(self) -> Result<()> {
574 self.close_table()?;
575 self.close_table()
576 }
577}
578
579#[cfg(test)]
580mod test {
581 use std::collections::HashMap;
582
583 use crate::nodes::{StringExpression, TableExpression};
584
585 use super::*;
586
587 macro_rules! expression {
588 ($input:literal) => {{
589 let mut block = $crate::Parser::default()
590 .parse(concat!("return ", $input))
591 .expect("expected code should parse");
592 let last = block
593 .take_last_statement()
594 .expect("last statement should exist");
595
596 match last {
597 $crate::nodes::LastStatement::Return(statement) => {
598 assert_eq!(statement.len(), 1);
599 statement.into_iter_expressions().next().unwrap()
600 }
601 $crate::nodes::LastStatement::Break(_)
602 | $crate::nodes::LastStatement::Continue(_) => {
603 panic!("unexpected last statement")
604 }
605 }
606 }};
607 }
608
609 macro_rules! test_serialize {
610 ($($name:ident($input:expr) => $value:expr),* $(,)?) => {
611 $(
612 #[test]
613 fn $name() {
614 pretty_assertions::assert_eq!(
615 to_expression(&$input).unwrap(),
616 Expression::from($value),
617 );
618 }
619 )*
620 };
621 }
622
623 test_serialize!(
624 serializes_true_value(true) => true,
625 serializes_false_value(false) => false,
626 serializes_one_number_value(1) => expression!("1"),
627 serializes_zero_as_i8(0_i8) => expression!("0"),
628 serializes_zero_as_i16(0_i8) => expression!("0"),
629 serializes_zero_as_u8(0_u8) => expression!("0"),
630 serializes_zero_as_u16(0_u16) => expression!("0"),
631 serializes_one_point_five_number_value(1.5) => expression!("1.5"),
632 serializes_100_as_f32_number_value(100.0_f32) => expression!("100"),
633 serializes_char_value('a') => StringExpression::from_value("a"),
634 serializes_str_value("abc") => StringExpression::from_value("abc"),
635 serializes_none_value(Option::<String>::None) => Expression::nil(),
636 serializes_unit_value(()) => Expression::nil(),
637 serializes_empty_vec_value(Vec::<bool>::new()) => TableExpression::default(),
638 serializes_tuple_with_bool((true,)) => expression!("{ true }"),
639 serializes_tuple_with_two_bool((false, true)) => expression!("{ false, true }"),
640 serializes_vec_with_bool(vec![true]) => expression!("{ true }"),
641 serializes_vec_with_two_bool(vec![true, false]) => expression!("{ true, false }"),
642 serializes_slice_of_strings(["a", "b", "c"]) => expression!("{ \"a\", \"b\", \"c\" }"),
643 serializes_slice_of_bytes(serde_bytes::Bytes::new("abc".as_bytes())) => expression!("string.char(0x61, 0x62, 0x63)"),
644 serializes_empty_hash_map(HashMap::<usize, usize>::new()) => expression!("{}"),
645 serializes_hash_map_with_string_to_bool({
646 let mut map = HashMap::new();
647 map.insert("oof", true);
648 map
649 }) => expression!("{ oof = true }"),
650 serializes_hash_map_with_keyword_string_to_vec({
651 let mut map = HashMap::new();
652 map.insert("do", vec![1, 2, 3]);
653 map
654 }) => expression!("{ [\"do\"] = {1, 2, 3} }"),
655 serializes_hash_map_with_bool_to_number({
656 let mut map = HashMap::new();
657 map.insert(false, 0);
658 map
659 }) => expression!("{ [false] = 0 }"),
660 serializes_struct_with_int_field({
661 #[derive(Serialize)]
662 struct Test {
663 int: u32,
664 }
665
666 Test { int: 1 }
667 }) => expression!("{ int = 1 }"),
668 serializes_struct_with_int_and_vec_fields({
669 #[derive(Serialize)]
670 struct Test {
671 int: u32,
672 seq: Vec<&'static str>,
673 }
674
675 Test {
676 int: 1,
677 seq: vec!["a", "b"],
678 }
679 }) => expression!("{ int = 1, seq = { 'a', 'b' } }"),
680 serializes_enum_unit_variant({
681 #[derive(Serialize)]
682 enum Test {
683 Unit,
684 }
685
686 Test::Unit
687 }) => StringExpression::from_value("Unit"),
688 serializes_enum_type_variant({
689 #[derive(Serialize)]
690 enum Test {
691 Value(bool),
692 }
693
694 Test::Value(true)
695 }) => expression!("{ Value = true }"),
696 serializes_enum_tuple_variant({
697 #[derive(Serialize)]
698 enum Test {
699 Tuple(&'static str, usize),
700 }
701
702 Test::Tuple("oof", 0)
703 }) => expression!("{ Tuple = { 'oof', 0 } }"),
704 serializes_enum_struct_variant({
705 #[derive(Serialize)]
706 enum Test {
707 Struct {
708 field: &'static str,
709 pair: (bool, usize),
710 list: Vec<u32>,
711 }
712 }
713
714 Test::Struct {
715 field: "value",
716 pair: (false, 10),
717 list: vec![]
718 }
719 }) => expression!("{ Struct = { field = \"value\", pair = { false, 10 }, list = {} } }"),
720 serializes_enum_struct_variant_internally_tagged({
721 #[derive(Serialize)]
722 #[serde(tag = "type")]
723 enum Test {
724 Struct {
725 field: &'static str,
726 pair: (bool, usize),
727 list: Vec<u32>,
728 }
729 }
730
731 Test::Struct {
732 field: "value",
733 pair: (false, 10),
734 list: vec![]
735 }
736 }) => expression!("{ type = \"Struct\", field = \"value\", pair = { false, 10 }, list = {} }"),
737 serializes_enum_struct_variant_adjacently_tagged({
738 #[derive(Serialize)]
739 #[serde(tag = "type", content = "data")]
740 enum Test {
741 Struct {
742 field: &'static str,
743 pair: (bool, usize),
744 list: Vec<u32>,
745 }
746 }
747
748 Test::Struct {
749 field: "value",
750 pair: (false, 10),
751 list: vec![]
752 }
753 }) => expression!("{ type = \"Struct\", data = { field = \"value\", pair = { false, 10 }, list = {} } }"),
754 serializes_enum_struct_variant_untagged({
755 #[derive(Serialize)]
756 #[serde(untagged)]
757 enum Test {
758 Struct {
759 field: &'static str,
760 pair: (bool, usize),
761 list: Vec<u32>,
762 }
763 }
764
765 Test::Struct {
766 field: "value",
767 pair: (false, 10),
768 list: vec![]
769 }
770 }) => expression!("{ field = \"value\", pair = { false, 10 }, list = {} }"),
771 serializes_new_type_struct({
772 #[derive(Serialize)]
773 struct Test(String);
774
775 Test("value".to_owned())
776 }) => expression!("'value'"),
777 serializes_tuple_struct({
778 #[derive(Serialize)]
779 struct Test(String, usize, String);
780
781 Test("value".to_owned(), 1, "".to_owned())
782 }) => expression!("{ 'value', 1, '' }"),
783 );
784}