pub struct Rendered {
pub width: u32,
pub height: u32,
pub pixels: Vec<u8>,
}Expand description
A rendered bitmap: 8-bit RGBA, row-major, no padding.
Fields§
§width: u32§height: u32§pixels: Vec<u8>Implementations§
Source§impl Rendered
impl Rendered
Sourcepub fn diff_count(&self, other: &Rendered, tolerance: u8) -> u32
pub fn diff_count(&self, other: &Rendered, tolerance: u8) -> u32
Number of pixels differing from other by more than tolerance in any
channel. u32::MAX if the dimensions differ.
Sourcepub fn distinct(&self) -> usize
pub fn distinct(&self) -> usize
How many distinct RGBA values the bitmap contains.
A render that came out blank has one; a case whose diff is zero and whose colour count is one proved nothing, so the harness reports both.
Examples found in repository?
examples/swift_org_tutorial.rs (line 202)
185fn main() {
186 // `--sim` and `--device` build for iOS and run it there; see `common/simulator.rs`.
187 if std::env::args().any(|a| a == "--sim" || a == "device" || a == "ipa") {
188 return simulator::main(&simulator::Bundle {
189 example: "swift_org_tutorial",
190 bundle_id: "dev.rswift.WhyNotTry",
191 executable: "WhyNotTry",
192 display_name: "Why not try…",
193 launch_args: &[],
194 });
195 }
196 // `--render` draws one frame to a PNG instead of opening a window, so the
197 // result can be looked at without a display.
198 if std::env::args().any(|a| a == "--render") {
199 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tutorial.png");
200 let frame = swiftui_native::render::render(&content_view(), 420, 640);
201 frame.write_png(out);
202 eprintln!("wrote {out} ({} colours)", frame.distinct());
203 return;
204 }
205 // `WindowGroup { ContentView() }` — the same tree the tutorial's `App` hosts.
206 show_window(&content_view(), "Why not try…", 420.0, 640.0);
207}Sourcepub fn write_png(&self, path: &str) -> bool
pub fn write_png(&self, path: &str) -> bool
Write a PNG for eyeballing.
NSBitmapImageRep on the Mac, so the file matches what the macOS
capture paths produced byte for byte; CoreGraphics and ImageIO
elsewhere, which are the same API on every Apple platform.
Examples found in repository?
examples/todo.rs (line 152)
140fn main() {
141 if std::env::args().any(|a| a == "--sim" || a == "device") {
142 return simulator::main(&simulator::Bundle {
143 example: "todo",
144 bundle_id: "dev.rswift.Todo",
145 executable: "Todo",
146 display_name: "Todo",
147 launch_args: &[],
148 });
149 }
150 if std::env::args().any(|a| a == "--render") {
151 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/todo.png");
152 swiftui_native::render::render(&content_view(), 420, 460).write_png(out);
153 eprintln!("wrote {out}");
154 return;
155 }
156 show_window(&content_view(), "Todo", 420.0, 460.0);
157}More examples
examples/inbox.rs (line 143)
131fn main() {
132 if std::env::args().any(|a| a == "--sim" || a == "device") {
133 return simulator::main(&simulator::Bundle {
134 example: "inbox",
135 bundle_id: "dev.rswift.Inbox",
136 executable: "Inbox",
137 display_name: "Inbox",
138 launch_args: &[],
139 });
140 }
141 if std::env::args().any(|a| a == "--render") {
142 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/inbox.png");
143 swiftui_native::render::render(&content_view(), 420, 520).write_png(out);
144 eprintln!("wrote {out}");
145 return;
146 }
147 show_window(&content_view(), "Inbox", 420.0, 520.0);
148}examples/settings.rs (line 141)
129fn main() {
130 if std::env::args().any(|a| a == "--sim" || a == "device") {
131 return simulator::main(&simulator::Bundle {
132 example: "settings",
133 bundle_id: "dev.rswift.Settings",
134 executable: "Settings",
135 display_name: "Settings",
136 launch_args: &[],
137 });
138 }
139 if std::env::args().any(|a| a == "--render") {
140 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/settings.png");
141 swiftui_native::render::render(&content_view(), 420, 640).write_png(out);
142 eprintln!("wrote {out}");
143 return;
144 }
145 show_window(&content_view(), "Settings", 420.0, 640.0);
146}examples/dashboard.rs (line 119)
107fn main() {
108 if std::env::args().any(|a| a == "--sim" || a == "device") {
109 return simulator::main(&simulator::Bundle {
110 example: "dashboard",
111 bundle_id: "dev.rswift.Dashboard",
112 executable: "Dashboard",
113 display_name: "Dashboard",
114 launch_args: &[],
115 });
116 }
117 if std::env::args().any(|a| a == "--render") {
118 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/dashboard.png");
119 swiftui_native::render::render(&content_view(), 420, 480).write_png(out);
120 eprintln!("wrote {out}");
121 return;
122 }
123 show_window(&content_view(), "Dashboard", 420.0, 480.0);
124}examples/swift_org_tutorial.rs (line 201)
185fn main() {
186 // `--sim` and `--device` build for iOS and run it there; see `common/simulator.rs`.
187 if std::env::args().any(|a| a == "--sim" || a == "device" || a == "ipa") {
188 return simulator::main(&simulator::Bundle {
189 example: "swift_org_tutorial",
190 bundle_id: "dev.rswift.WhyNotTry",
191 executable: "WhyNotTry",
192 display_name: "Why not try…",
193 launch_args: &[],
194 });
195 }
196 // `--render` draws one frame to a PNG instead of opening a window, so the
197 // result can be looked at without a display.
198 if std::env::args().any(|a| a == "--render") {
199 let out = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target/tutorial.png");
200 let frame = swiftui_native::render::render(&content_view(), 420, 640);
201 frame.write_png(out);
202 eprintln!("wrote {out} ({} colours)", frame.distinct());
203 return;
204 }
205 // `WindowGroup { ContentView() }` — the same tree the tutorial's `App` hosts.
206 show_window(&content_view(), "Why not try…", 420.0, 640.0);
207}examples/dynamic_ui.rs (line 242)
208fn repl() {
209 use std::io::{BufRead, Write};
210 eprintln!("Type a screen. Blank line renders it; Ctrl-D quits.");
211 eprintln!("Names: {}", spec::NAMES.join(" "));
212 let stdin = std::io::stdin();
213 let mut buf = String::new();
214 let mut n = 0usize;
215 loop {
216 eprint!("> ");
217 let _ = std::io::stderr().flush();
218 let mut line = String::new();
219 match stdin.lock().read_line(&mut line) {
220 Ok(0) => break,
221 Ok(_) => {}
222 Err(e) => {
223 eprintln!("{e}");
224 break;
225 }
226 }
227 if line.trim().is_empty() {
228 if buf.trim().is_empty() {
229 continue;
230 }
231 match spec::parse(&buf).and_then(|nodes| spec::build(&nodes)) {
232 Ok(v) => {
233 n += 1;
234 let out = format!(
235 "{}/../../target/dynamic_ui_repl_{n}.png",
236 env!("CARGO_MANIFEST_DIR")
237 );
238 let handle = v.into_handle();
239 eprintln!(" {}", swiftui_native::diag::type_name(
240 swiftui_native::views::meta_of(&handle)
241 ));
242 if swiftui_native::render::render(&handle, 420, 420).write_png(&out) {
243 eprintln!(" wrote {out}");
244 }
245 }
246 Err(e) => eprintln!(" {e}"),
247 }
248 buf.clear();
249 } else {
250 buf.push_str(&line);
251 }
252 }
253}
254
255/// Print the Swift type a spec builds.
256///
257/// The strongest short proof that this is real SwiftUI and not a lookalike: the
258/// name comes from the Swift runtime's own metadata, and it is a different name
259/// for every different spec.
260fn print_type(arg: &str) -> i32 {
261 match load(arg).and_then(|s| {
262 spec::parse(&s).and_then(|nodes| spec::build(&nodes)).map(|v| v.into_handle())
263 }) {
264 Ok(h) => {
265 println!(
266 "{}",
267 swiftui_native::diag::type_name(swiftui_native::views::meta_of(&h))
268 );
269 0
270 }
271 Err(e) => {
272 eprintln!("{e}");
273 1
274 }
275 }
276}
277
278#[cfg(target_os = "macos")]
279fn main() {
280 let args: Vec<String> = std::env::args().skip(1).collect();
281 let flag = |f: &str| args.iter().any(|a| a == f);
282
283 if flag("--names") {
284 println!("{}", spec::NAMES.join("\n"));
285 return;
286 }
287 if flag("--repl") {
288 return repl();
289 }
290 if let Some(i) = args.iter().position(|a| a == "--type") {
291 let Some(arg) = args.get(i + 1) else {
292 eprintln!("--type wants a spec: a path, `-`, or a demo name");
293 std::process::exit(2);
294 };
295 std::process::exit(print_type(arg));
296 }
297 if flag("--render") {
298 // One PNG per built-in spec. Different text, different Swift type,
299 // different picture — from one binary, in one process.
300 for (name, src) in DEMOS {
301 set_spec(src);
302 // The spec's own view, for the type name: `content_view` wraps it
303 // in the runtime-synthesised `RustView` that carries `@State`, and
304 // that wrapper is the same whatever the spec says. What differs —
305 // and what makes the point — is the type underneath it.
306 let built = body().into_handle();
307 let out = format!("{}/../../target/dynamic_ui_{name}.png", env!("CARGO_MANIFEST_DIR"));
308 let ok = swiftui_native::render::render(&content_view(), 380, 420).write_png(&out);
309 println!(
310 "{name:10} {}\n {}",
311 swiftui_native::diag::type_name(swiftui_native::views::meta_of(&built)),
312 if ok { out } else { "render failed".to_string() }
313 );
314 }
315 return;
316 }
317 if flag("--sim") {
318 return simulator::main(&simulator::Bundle {
319 example: "dynamic_ui",
320 bundle_id: "dev.rswift.DynamicUI",
321 executable: "DynamicUI",
322 display_name: "Dynamic UI",
323 launch_args: &[],
324 });
325 }
326
327 // A path or a demo name, else the first demo.
328 if let Some(arg) = args.iter().find(|a| !a.starts_with("--")) {
329 match load(arg) {
330 Ok(s) => set_spec(&s),
331 Err(e) => {
332 eprintln!("{e}");
333 std::process::exit(1);
334 }
335 }
336 }
337 show_window(&content_view(), "Dynamic UI", 380.0, 460.0);
338}Additional examples can be found in:
Auto Trait Implementations§
impl Freeze for Rendered
impl RefUnwindSafe for Rendered
impl Send for Rendered
impl Sync for Rendered
impl Unpin for Rendered
impl UnsafeUnpin for Rendered
impl UnwindSafe for Rendered
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more