Skip to main content

serializer/
optimizer.rs

1/// Ultra-optimization rules for DX SINGULARITY format
2///
3/// These rules transform verbose keys into minimal byte-efficient forms
4/// while maintaining clarity through the editor's display layer.
5use std::collections::HashMap;
6
7/// Ultra-optimization rule: abbreviate common keys
8#[must_use]
9pub fn optimize_key(key: &str) -> String {
10    // Common abbreviations map
11    let abbrev: HashMap<&str, &str> = [
12        // Core metadata
13        ("name", "n"),
14        ("version", "v"),
15        ("title", "t"),
16        ("description", "d"),
17        ("desc", "d"),
18        ("author", "a"),
19        ("license", "lic"),
20        // Context/Config
21        ("context", "c"),
22        ("config", "cfg"),
23        ("settings", "set"),
24        // Development
25        ("languages", "l"),
26        ("language", "lg"),
27        ("runtime", "rt"),
28        ("compiler", "cp"),
29        ("bundler", "bd"),
30        ("packageManager", "pm"),
31        ("package_manager", "pm"),
32        ("framework", "fw"),
33        // Project structure
34        ("forge", "f"),
35        ("repository", "r"),
36        ("repo", "r"),
37        ("container", "c"),
38        ("workspace", "ws"),
39        ("workspaces", "ws"),
40        // UI/Style
41        ("style", "s"),
42        ("styles", "s"),
43        ("theme", "th"),
44        ("themes", "th"),
45        ("engine", "e"),
46        ("ui", "u"),
47        ("component", "cmp"),
48        ("components", "cmp"),
49        // Media
50        ("media", "m"),
51        ("image", "img"),
52        ("images", "img"),
53        ("video", "vid"),
54        ("videos", "vid"),
55        ("sound", "snd"),
56        ("sounds", "snd"),
57        ("audio", "aud"),
58        ("asset", "ast"),
59        ("assets", "ast"),
60        // i18n
61        ("internationalization", "i"),
62        ("i18n", "i"),
63        ("locale", "loc"),
64        ("locales", "loc"),
65        ("translation", "tr"),
66        ("translations", "tr"),
67        // Common properties
68        ("path", "p"),
69        ("default", "d"),
70        ("primary", "pr"),
71        ("secondary", "sc"),
72        ("variant", "vr"),
73        ("pack", "pk"),
74        ("items", "i"),
75        ("item", "i"),
76        // Environment
77        ("development", "dev"),
78        ("production", "prod"),
79        ("test", "tst"),
80        // IDE/Tools
81        ("icon", "ic"),
82        ("icons", "ic"),
83        ("font", "fn"),
84        ("fonts", "fn"),
85        ("ide", "id"),
86    ]
87    .iter()
88    .copied()
89    .collect();
90
91    // Check if we have an abbreviation
92    if let Some(short) = abbrev.get(key) {
93        return short.to_string();
94    }
95
96    // Apply 2-letter language codes
97    match key {
98        "javascript" => return "js".to_string(),
99        "typescript" => return "ts".to_string(),
100        "javascript/typescript" => return "js/ts".to_string(),
101        "python" => return "py".to_string(),
102        "rust" => return "rs".to_string(),
103        "golang" => return "go".to_string(),
104        _ => {}
105    }
106
107    // If no abbreviation, use first 2-3 chars for long keys
108    if key.len() > 8 {
109        return key.chars().take(3).collect();
110    }
111
112    key.to_string()
113}
114
115/// Optimize a nested key path (e.g., "media.images.path" -> "m.img.p")
116#[must_use]
117pub fn optimize_path(path: &str) -> String {
118    path.split('.')
119        .map(optimize_key)
120        .collect::<Vec<_>>()
121        .join(".")
122}
123
124/// Determine if values should be inlined with ^ operator
125#[must_use]
126pub fn should_inline(values: &[(String, String)]) -> bool {
127    // Inline if:
128    // 1. Less than 5 items
129    // 2. Total length < 150 chars
130    // 3. All values are simple (no nested objects/arrays)
131
132    if values.len() > 4 {
133        return false;
134    }
135
136    let total_len: usize = values
137        .iter()
138        .map(|(k, v)| k.len() + v.len() + 2) // key:val^
139        .sum();
140
141    total_len < 150
142}
143
144/// Optimize array/list items (use pipe separator)
145#[must_use]
146pub fn format_array(items: &[String]) -> String {
147    items.join("|")
148}
149
150/// Detect if a value should use dash for null/empty
151#[must_use]
152pub fn format_null_value() -> &'static str {
153    "-"
154}
155
156#[cfg(test)]
157mod tests {
158    use super::*;
159
160    #[test]
161    fn test_key_optimization() {
162        assert_eq!(optimize_key("name"), "n");
163        assert_eq!(optimize_key("version"), "v");
164        assert_eq!(optimize_key("description"), "d");
165        assert_eq!(optimize_key("packageManager"), "pm");
166        assert_eq!(optimize_key("javascript/typescript"), "js/ts");
167    }
168
169    #[test]
170    fn test_path_optimization() {
171        assert_eq!(optimize_path("media.images.path"), "m.img.p");
172        assert_eq!(optimize_path("i18n.locales.default"), "i.loc.d");
173    }
174
175    #[test]
176    fn test_array_format() {
177        let items = vec!["cli".to_string(), "docs".to_string(), "tests".to_string()];
178        assert_eq!(format_array(&items), "cli|docs|tests");
179    }
180}