11use crate :: { StdFunction , StdlibModule , StdlibRegistry } ;
22use std:: cell:: RefCell ;
33use std:: collections:: HashMap ;
4+ // Performance Note:
5+ // This module uses `std::fmt::Write` and the `write!` macro instead of `push_str(&format!(...))`
6+ // to append content to SVG and buffer strings. This prevents the allocation of temporary `String`
7+ // objects during concatenation, significantly reducing memory overhead when rendering complex canvases.
8+ use std:: fmt:: Write ;
49use std:: rc:: Rc ;
510use techscript_runtime:: {
611 context:: { Capability , RuntimeContext } ,
@@ -38,10 +43,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
3843 . and_then ( |p| p. value . as_ref ( ) )
3944 . and_then ( |v| v. try_into_int ( ) . ok ( ) )
4045 . unwrap_or ( 48 ) ;
41- svg. push_str ( & format ! (
46+ let _ = write ! (
47+ svg,
4248 r#"<text x="250" y="440" text-anchor="middle" dominant-baseline="central" font-size="{}" font-weight="800" fill="{}" font-family="system-ui, -apple-system, sans-serif" letter-spacing="3">{}</text>"# ,
4349 size, color, text
44- ) ) ;
50+ ) ;
4551 }
4652 "rings" => {
4753 // BLUE FLAME / WING (Bottom-Left Swirl)
@@ -98,10 +104,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
98104 . and_then ( |p| p. value . as_ref ( ) )
99105 . and_then ( |v| v. try_into_int ( ) . ok ( ) )
100106 . unwrap_or ( 48 ) ;
101- svg. push_str ( & format ! (
107+ let _ = write ! (
108+ svg,
102109 r#"<text x="250" y="380" text-anchor="middle" dominant-baseline="central" font-size="{}" font-weight="800" fill="{}" font-family="system-ui, -apple-system, sans-serif" letter-spacing="3">{}</text>"# ,
103110 size, color, text
104- ) ) ;
111+ ) ;
105112 }
106113 "rings" => {
107114 let count = dsl
@@ -135,10 +142,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
135142 for i in 0 ..count {
136143 let r = 80 + i as i64 * ( size / 2 ) ;
137144 let opacity = 0.4 - ( i as f32 * 0.08 ) ;
138- svg. push_str ( & format ! (
145+ let _ = write ! (
146+ svg,
139147 r#"<circle cx="250" cy="180" r="{}" fill="none" stroke="{}" stroke-width="{}" opacity="{}"/>"# ,
140148 r, color, thickness, opacity
141- ) ) ;
149+ ) ;
142150 }
143151 }
144152 "emblem" => {
@@ -158,10 +166,16 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
158166 . unwrap_or ( 120 ) ;
159167 let x = 250 - size / 2 ;
160168 let y = 180 - size / 2 ;
161- svg. push_str ( & format ! (
169+ let _ = write ! (
170+ svg,
162171 r#"<rect x="{}" y="{}" width="{}" height="{}" rx="{}" fill="{}" transform="rotate(45 250 180)" filter="url(#glow)"/>"# ,
163- x, y, size, size, size / 4 , color
164- ) ) ;
172+ x,
173+ y,
174+ size,
175+ size,
176+ size / 4 ,
177+ color
178+ ) ;
165179 }
166180 "letter" => {
167181 let ch = dsl
@@ -185,10 +199,11 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
185199 . and_then ( |p| p. value . as_ref ( ) )
186200 . and_then ( |v| v. try_into_int ( ) . ok ( ) )
187201 . unwrap_or ( 32 ) ;
188- svg. push_str ( & format ! (
202+ let _ = write ! (
203+ svg,
189204 r#"<text x="250" y="180" text-anchor="middle" dominant-baseline="central" font-size="{}" font-weight="900" fill="{}" font-family="system-ui, -apple-system, sans-serif">{}</text>"# ,
190205 size, color, ch
191- ) ) ;
206+ ) ;
192207 }
193208 "core" => {
194209 let color = dsl
@@ -205,11 +220,12 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
205220 . and_then ( |p| p. value . as_ref ( ) )
206221 . and_then ( |v| v. try_into_int ( ) . ok ( ) )
207222 . unwrap_or ( 40 ) ;
208- svg. push_str ( & format ! (
223+ let _ = write ! (
224+ svg,
209225 r#"<circle cx="250" cy="180" r="{}" fill="{}" opacity="0.8"/>"# ,
210226 size / 2 ,
211227 color
212- ) ) ;
228+ ) ;
213229 }
214230 "circuits" => {
215231 let color = dsl
@@ -219,15 +235,16 @@ fn dsl_to_svg(val: &RuntimeValue, is_dragon: bool) -> String {
219235 . and_then ( |p| p. value . as_ref ( ) )
220236 . map ( |v| v. to_string ( ) )
221237 . unwrap_or_else ( || "#00d4ff" . to_string ( ) ) ;
222- svg. push_str ( & format ! (
238+ let _ = write ! (
239+ svg,
223240 r#"<line x1="50" y1="180" x2="450" y2="180" stroke="{}" stroke-width="1.5" stroke-dasharray="5 5" opacity="0.6"/>
224241 <line x1="250" y1="30" x2="250" y2="330" stroke="{}" stroke-width="1.5" stroke-dasharray="5 5" opacity="0.6"/>
225242 <circle cx="50" cy="180" r="4" fill="{}"/>
226243 <circle cx="450" cy="180" r="4" fill="{}"/>
227244 <circle cx="250" cy="30" r="4" fill="{}"/>
228245 <circle cx="250" cy="330" r="4" fill="{}"/>"# ,
229246 color, color, color, color, color, color
230- ) ) ;
247+ ) ;
231248 }
232249 _ => { }
233250 }
@@ -292,10 +309,11 @@ impl Callable for CanvasFn {
292309 let w = parse_width ( & buf) ;
293310 let h = parse_height ( & buf) ;
294311 let fill = args[ 0 ] . to_string ( ) ;
295- buf. push_str ( & format ! (
312+ let _ = write ! (
313+ buf,
296314 r#"<rect x="0" y="0" width="{}" height="{}" fill="{}"/>"# ,
297315 w, h, fill
298- ) ) ;
316+ ) ;
299317 Ok ( RuntimeValue :: Null )
300318 }
301319 CanvasOp :: Rect => {
@@ -304,21 +322,23 @@ impl Callable for CanvasFn {
304322 let w = args[ 2 ] . try_into_int ( ) . unwrap_or ( 100 ) ;
305323 let h = args[ 3 ] . try_into_int ( ) . unwrap_or ( 100 ) ;
306324 let fill = args[ 4 ] . to_string ( ) ;
307- buf. push_str ( & format ! (
325+ let _ = write ! (
326+ buf,
308327 r#"<rect x="{}" y="{}" width="{}" height="{}" fill="{}"/>"# ,
309328 x, y, w, h, fill
310- ) ) ;
329+ ) ;
311330 Ok ( RuntimeValue :: Null )
312331 }
313332 CanvasOp :: Circle => {
314333 let cx = args[ 0 ] . try_into_int ( ) . unwrap_or ( 50 ) ;
315334 let cy = args[ 1 ] . try_into_int ( ) . unwrap_or ( 50 ) ;
316335 let r = args[ 2 ] . try_into_int ( ) . unwrap_or ( 40 ) ;
317336 let fill = args[ 3 ] . to_string ( ) ;
318- buf. push_str ( & format ! (
337+ let _ = write ! (
338+ buf,
319339 r#"<circle cx="{}" cy="{}" r="{}" fill="{}"/>"# ,
320340 cx, cy, r, fill
321- ) ) ;
341+ ) ;
322342 Ok ( RuntimeValue :: Null )
323343 }
324344 CanvasOp :: Text => {
@@ -335,16 +355,17 @@ impl Callable for CanvasFn {
335355 } else {
336356 "black" . to_string ( )
337357 } ;
338- buf. push_str ( & format ! ( r#"<text x="{}" y="{}" font-size="{}" font-family="Arial,sans-serif" fill="{}">{}</text>"# , x, y, size, color, txt) ) ;
358+ let _ = write ! (
359+ buf,
360+ r#"<text x="{}" y="{}" font-size="{}" font-family="Arial,sans-serif" fill="{}">{}</text>"# ,
361+ x, y, size, color, txt
362+ ) ;
339363 Ok ( RuntimeValue :: Null )
340364 }
341365 CanvasOp :: Polygon => {
342366 let points = args[ 0 ] . to_string ( ) ;
343367 let fill = args[ 1 ] . to_string ( ) ;
344- buf. push_str ( & format ! (
345- r#"<polygon points="{}" fill="{}"/>"# ,
346- points, fill
347- ) ) ;
368+ let _ = write ! ( buf, r#"<polygon points="{}" fill="{}"/>"# , points, fill) ;
348369 Ok ( RuntimeValue :: Null )
349370 }
350371 CanvasOp :: Line => {
@@ -353,10 +374,11 @@ impl Callable for CanvasFn {
353374 let x2 = args[ 2 ] . try_into_int ( ) . unwrap_or ( 100 ) ;
354375 let y2 = args[ 3 ] . try_into_int ( ) . unwrap_or ( 100 ) ;
355376 let stroke = args[ 4 ] . to_string ( ) ;
356- buf. push_str ( & format ! (
377+ let _ = write ! (
378+ buf,
357379 r#"<line x1="{}" y1="{}" x2="{}" y2="{}" stroke="{}" stroke-width="2"/>"# ,
358380 x1, y1, x2, y2, stroke
359- ) ) ;
381+ ) ;
360382 Ok ( RuntimeValue :: Null )
361383 }
362384 CanvasOp :: Close => {
@@ -405,7 +427,11 @@ impl Callable for CanvasFn {
405427 } else {
406428 "1" . to_string ( )
407429 } ;
408- buf. push_str ( & format ! ( r#"<circle cx="{}" cy="{}" r="{}" fill="none" stroke="{}" stroke-width="{}" opacity="{}"/>"# , cx, cy, r, color, width, opacity) ) ;
430+ let _ = write ! (
431+ buf,
432+ r#"<circle cx="{}" cy="{}" r="{}" fill="none" stroke="{}" stroke-width="{}" opacity="{}"/>"# ,
433+ cx, cy, r, color, width, opacity
434+ ) ;
409435 Ok ( RuntimeValue :: Null )
410436 }
411437 CanvasOp :: Reset => {
@@ -633,7 +659,7 @@ impl StdlibRegistry {
633659 let bg_color = if is_dragon { "#030408" } else { "#0a0e27" } ;
634660
635661 let mut svg = String :: new ( ) ;
636- svg . push_str ( & format ! ( r##"<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
662+ let _ = write ! ( svg , r##"<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
637663 <defs>
638664 <filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
639665 <feGaussianBlur stdDeviation="6" result="blur" />
@@ -656,7 +682,7 @@ impl StdlibRegistry {
656682 </linearGradient>
657683 </defs>
658684 <rect width="100%" height="100%" fill="{}"/>
659- "## , bg_color) ) ;
685+ "## , bg_color) ;
660686 for block in & blocks {
661687 svg. push_str ( & dsl_to_svg ( block, is_dragon) ) ;
662688 }
0 commit comments