frozen_collections_core/emit/
collection_entry.rs1#![expect(clippy::redundant_pub_crate, reason = "Helps clarity")]
2
3use core::fmt::{Debug, Formatter};
4use proc_macro2::TokenStream;
5use quote::{ToTokens, quote};
6use syn::{Expr, parse_quote};
7
8#[cfg(feature = "macros")]
9pub(crate) struct NonLiteralKey;
10
11pub struct CollectionEntry<K> {
13 pub(crate) key: K,
14 key_expr: Expr,
15 pub(crate) value_expr: Expr,
16}
17
18impl<K> CollectionEntry<K> {
19 pub const fn map_entry(key: K, key_expr: Expr, value_expr: Expr) -> Self {
21 Self { key, key_expr, value_expr }
22 }
23
24 pub fn set_entry(value: K, value_expr: Expr) -> Self {
26 Self {
27 key: value,
28 key_expr: value_expr,
29 value_expr: parse_quote!(()),
30 }
31 }
32}
33
34impl<K> ToTokens for CollectionEntry<K> {
35 fn to_tokens(&self, tokens: &mut TokenStream) {
36 let key = &self.key_expr;
37 let value = &self.value_expr;
38 tokens.extend(quote!((#key, #value)));
39 }
40}
41
42impl<K> Clone for CollectionEntry<K>
43where
44 K: Clone,
45{
46 fn clone(&self) -> Self {
47 Self {
48 key: self.key.clone(),
49 key_expr: self.key_expr.clone(),
50 value_expr: self.value_expr.clone(),
51 }
52 }
53}
54
55impl<K> Debug for CollectionEntry<K>
56where
57 K: Debug,
58{
59 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
60 write!(
61 f,
62 "CollectionEntry {{ key: {:?}, key_expr '{}', value_expr: '{}'}}",
63 self.key,
64 self.key_expr.to_token_stream(),
65 self.value_expr.to_token_stream()
66 )
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use syn::parse_quote;
74
75 #[test]
76 fn test_map_entry() {
77 let key = "key";
78 let key_expr: Expr = parse_quote!(key);
79 let value_expr: Expr = parse_quote!(value);
80 let entry = CollectionEntry::map_entry(key, key_expr.clone(), value_expr.clone());
81
82 assert_eq!(entry.key, key);
83 assert_eq!(entry.key_expr, key_expr);
84 assert_eq!(entry.value_expr, value_expr);
85 }
86
87 #[test]
88 fn test_set_entry() {
89 let value = "value";
90 let value_expr: Expr = parse_quote!(value);
91 let entry = CollectionEntry::set_entry(value, value_expr.clone());
92
93 assert_eq!(entry.key, value);
94 assert_eq!(entry.key_expr, value_expr);
95 assert_eq!(entry.value_expr, parse_quote!(()));
96 }
97
98 #[test]
99 fn test_to_tokens() {
100 let key_expr: Expr = parse_quote!(key);
101 let value_expr: Expr = parse_quote!(value);
102 let entry = CollectionEntry::map_entry("key", key_expr, value_expr);
103 let mut tokens = TokenStream::new();
104 entry.to_tokens(&mut tokens);
105
106 assert_eq!(tokens.to_string(), "(key , value)");
107 }
108
109 #[test]
110 fn test_clone() {
111 let key = "key";
112 let key_expr: Expr = parse_quote!(key);
113 let value_expr: Expr = parse_quote!(value);
114 let entry = CollectionEntry::map_entry(key, key_expr.clone(), value_expr.clone());
115 let cloned_entry = entry.clone();
116
117 assert_eq!(cloned_entry.key, key);
118 assert_eq!(cloned_entry.key_expr, key_expr);
119 assert_eq!(cloned_entry.value_expr, value_expr);
120 }
121
122 #[test]
123 fn test_debug() {
124 let key = "key";
125 let key_expr: Expr = parse_quote!(key);
126 let value_expr: Expr = parse_quote!(value);
127 let entry = CollectionEntry::map_entry(key, key_expr, value_expr);
128 let debug_str = format!("{entry:?}");
129
130 assert_eq!(debug_str, "CollectionEntry { key: \"key\", key_expr 'key', value_expr: 'value'}");
131 }
132}