//! Round-19 CPU/alloc micro-pack (no Postgres). //! //! Same rule as ROUND2–18: each section is BEFORE (verbatim replica of the //! shipped-before shape) vs AFTER (the shipped function itself where reachable — //! `common::fmt::compact_ical_utc` — else a verbatim replica of the shipped-after //! shape), with a byte/-value equivalence gate and a `GATE FAIL … rollback` //! check that exits non-zero if the AFTER arm fails to beat its BEFORE — the //! round's roll-back rule encoded into the benchmark. //! //! [M1] `AppPasswordService::verify_basic_auth` builds the moka cache key as //! `blake3::hash(format!("{username}:{password}").as_bytes())` on EVERY //! Basic-auth DAV/CalDAV/CardDAV/NextCloud request (before the cache //! lookup, so even cache hits pay it). The `format!` heap-allocates one //! throw-away `String` per request purely to feed bytes to blake3. The //! shipped-after form streams the same bytes into an incremental //! `blake3::Hasher` — byte-identical 32-byte key, zero allocation. //! //! [M2] `WopiTokenService::validate_token` / `generate_token` rebuilt a //! `Validation` (allocates a `required_spec_claims` HashSet + an //! `algorithms` Vec) and a `DecodingKey`/`EncodingKey` (copies the secret //! into a fresh Vec) on EVERY WOPI protocol call — Office/Collabora hosts //! poll these continuously. The shipped-after form prebuilds all three as //! struct fields in `new()` (exactly what `JwtTokenService` already does). //! //! [V1] `contact_to_vcard` / `generate_vcard` emit, per contact in every //! CardDAV REPORT / multiget / PROPFIND-with-address-data: //! - FN fallback `format!("{first} {last}").trim().to_string()` dropped //! the throwaway `.to_string()` copy (writes the borrowed trim slice); //! - NOTE `notes.replace('\n', "\\n")` allocated a full copy even when //! the note has no newline — now guarded (`contains('\n')`), the //! common no-newline note writes the borrowed slice directly; //! - REV `updated_at.format("%Y%m%dT%H%M%SZ")` ran chrono's strftime //! interpreter — now `common::fmt::compact_ical_utc` (stack LUT). //! //! [V2] REV/DTSTAMP stamp isolated: chrono `.format("%Y%m%dT%H%M%SZ")` vs the //! new `common::fmt::compact_ical_utc` stack renderer (CPU / wall gate). //! //! [M4] `trash_service::row_to_item_dto` `clone()`d `name` / `path` / //! `blob_hash` out of an OWNED `row` that is dropped at fn end — now //! moved (the favorites / recent / folder row mappers already move these //! same fields). //! //! [M5] `SearchUseCase::search` built the cache-key user segment via //! `user_id.to_string()` (heap) to feed `create_cache_key`'s hasher — now //! stack-encoded via `Uuid::hyphenated().encode_lower(&mut [u8; 36])`, //! byte-identical string ⇒ identical u64 key, zero allocation. //! //! [M6] WebDAV streaming PROPFIND built each child `href` with a fresh //! `format!` per row (up to 500 rows/page) — now a single buffer reused //! across the page (`clear` + `push_str` + `extend`). //! //! [M7] `nextcloud::session::extract_url_user` forced `.into_owned()` on the //! `urlencoding::decode` `Cow` on EVERY path-scoped NC DAV request, even //! though a plain-ASCII username decodes to `Cow::Borrowed` — now returns //! the `Cow` and compares by `.as_ref()`, zero-alloc on the common path. //! //! Run: //! cargo run --release --features bench --example bench_round19_micro //! Tunables (env): BENCH_ITERS (200000) use std::alloc::{GlobalAlloc, Layout, System}; use std::collections::hash_map::DefaultHasher; use std::env; use std::fmt::Write as _; use std::hash::{Hash, Hasher}; use std::hint::black_box; use std::sync::atomic::{AtomicU64, Ordering}; use std::time::Instant; use chrono::{DateTime, TimeZone, Utc}; use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation, decode, encode}; use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, utf8_percent_encode}; use serde::{Deserialize, Serialize}; use uuid::Uuid; static ALLOC_CALLS: AtomicU64 = AtomicU64::new(0); struct CountingAlloc; unsafe impl GlobalAlloc for CountingAlloc { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { ALLOC_CALLS.fetch_add(1, Ordering::Relaxed); unsafe { System.alloc(layout) } } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { unsafe { System.dealloc(ptr, layout) } } unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { ALLOC_CALLS.fetch_add(1, Ordering::Relaxed); unsafe { System.realloc(ptr, layout, new_size) } } unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { ALLOC_CALLS.fetch_add(1, Ordering::Relaxed); unsafe { System.alloc_zeroed(layout) } } } #[global_allocator] static GLOBAL: CountingAlloc = CountingAlloc; fn env_or(key: &str, default: T) -> T { env::var(key) .ok() .and_then(|v| v.parse().ok()) .unwrap_or(default) } struct Measured { wall_ns_per_op: f64, allocs_per_op: f64, } fn measure(iters: usize, mut f: F) -> Measured { // Warm up (grow any reused buffers, prime caches) so the measured window // reflects steady state, not first-touch growth. for _ in 0..(iters / 20).max(1) { f(); } let a0 = ALLOC_CALLS.load(Ordering::Relaxed); let t = Instant::now(); for _ in 0..iters { f(); } let wall = t.elapsed().as_nanos() as f64 / iters as f64; let allocs = (ALLOC_CALLS.load(Ordering::Relaxed) - a0) as f64 / iters as f64; Measured { wall_ns_per_op: wall, allocs_per_op: allocs, } } fn print_row(label: &str, m: &Measured) { println!( "| {:<48} | {:>12.1} | {:>10.2} |", label, m.wall_ns_per_op, m.allocs_per_op ); } fn header_footer(name: &str, before: &Measured, after: &Measured) { println!("| arm | ns/op | allocs/op |"); print_row(&format!("BEFORE {name}"), before); print_row(&format!("AFTER {name}"), after); println!( "# {:.2}x wall, {:.2} fewer allocs/op", before.wall_ns_per_op / after.wall_ns_per_op, before.allocs_per_op - after.allocs_per_op ); } fn gate_allocs(tag: &str, before: &Measured, after: &Measured) { if after.allocs_per_op >= before.allocs_per_op { eprintln!("GATE FAIL [{tag}]: AFTER did not reduce allocations — rollback"); std::process::exit(1); } } /// Wall gate for the CPU-only sections (identical alloc count both arms). /// Requires AFTER to be at least `min_ratio`× faster to guard against noise. fn gate_wall(tag: &str, before: &Measured, after: &Measured, min_ratio: f64) { let ratio = before.wall_ns_per_op / after.wall_ns_per_op; if ratio < min_ratio { eprintln!( "GATE FAIL [{tag}]: AFTER wall {:.1}ns not ≥{min_ratio:.2}× faster than BEFORE {:.1}ns (ratio {ratio:.2}) — rollback", after.wall_ns_per_op, before.wall_ns_per_op ); std::process::exit(1); } } // ──────────────────────────────────────────────────────────────────────────── // [M1] Basic-auth cache key — format! + hash vs incremental hasher // ──────────────────────────────────────────────────────────────────────────── fn m1_before(username: &str, password: &str) -> [u8; 32] { blake3::hash(format!("{}:{}", username, password).as_bytes()).into() } fn m1_after(username: &str, password: &str) -> [u8; 32] { let mut h = blake3::Hasher::new(); h.update(username.as_bytes()); h.update(b":"); h.update(password.as_bytes()); h.finalize().into() } fn section_m1() { let iters: usize = env_or("BENCH_ITERS", 200_000); let username = "benchuser@example.com"; let password = "Xk29-a83Q-p01M-77zL"; // NC app-password shape // Equivalence: the two forms feed blake3 the exact same byte stream. assert_eq!( m1_before(username, password), m1_after(username, password), "M1 cache key differs between BEFORE and AFTER" ); let before = measure(iters, || { black_box(m1_before(black_box(username), black_box(password))); }); let after = measure(iters, || { black_box(m1_after(black_box(username), black_box(password))); }); println!("\n## [M1] Basic-auth cache key (blake3)"); header_footer("verify_basic_auth cache-key hash", &before, &after); gate_allocs("M1", &before, &after); } // ──────────────────────────────────────────────────────────────────────────── // [M2] WOPI token validate — rebuilt Validation/DecodingKey vs prebuilt // ──────────────────────────────────────────────────────────────────────────── #[derive(Debug, Serialize, Deserialize)] struct BenchWopiClaims { sub: String, file_id: String, can_write: bool, scope: String, username: String, exp: i64, iat: i64, } fn m2_make_token(secret: &str) -> String { let claims = BenchWopiClaims { sub: "c410b103-7b86-4ac2-9eb4-3804351547be".into(), file_id: "0e72efc0-0d1c-45a1-b434-52336643b3f7".into(), can_write: true, scope: "wopi".into(), username: "bench_user".into(), exp: 4_102_444_799, // far future so validation passes iat: 1_700_000_000, }; encode( &Header::default(), &claims, &EncodingKey::from_secret(secret.as_bytes()), ) .expect("encode") } fn m2_before(secret: &str, token: &str) -> String { let validation = Validation::new(Algorithm::HS256); let data = decode::( token, &DecodingKey::from_secret(secret.as_bytes()), &validation, ) .expect("decode"); data.claims.file_id } fn m2_after(decoding_key: &DecodingKey, validation: &Validation, token: &str) -> String { let data = decode::(token, decoding_key, validation).expect("decode"); data.claims.file_id } fn section_m2() { let iters: usize = env_or("BENCH_ITERS", 200_000); let secret = "wopi_secret_at_least_32_bytes_long!!"; let token = m2_make_token(secret); // Prebuilt (shipped-after) config, mirroring WopiTokenService::new. let decoding_key = DecodingKey::from_secret(secret.as_bytes()); let validation = Validation::new(Algorithm::HS256); // Equivalence: same claim extracted. assert_eq!( m2_before(secret, &token), m2_after(&decoding_key, &validation, &token), "M2 decoded claim differs between BEFORE and AFTER" ); let before = measure(iters, || { black_box(m2_before(black_box(secret), black_box(&token))); }); let after = measure(iters, || { black_box(m2_after( black_box(&decoding_key), black_box(&validation), black_box(&token), )); }); println!("\n## [M2] WOPI token validate (prebuilt Validation/DecodingKey)"); header_footer("validate_token", &before, &after); gate_allocs("M2", &before, &after); } // ──────────────────────────────────────────────────────────────────────────── // [V1] vCard per-contact emit — FN fallback / NOTE / REV // ──────────────────────────────────────────────────────────────────────────── struct BenchContact { uid: String, first_name: Option, last_name: Option, full_name: Option, email: Vec<(String, String)>, notes: Option, updated_at: DateTime, } fn v1_before(c: &BenchContact) -> String { let mut vcard = String::with_capacity(256); vcard.push_str("BEGIN:VCARD\r\nVERSION:3.0\r\n"); let _ = write!(vcard, "UID:{}\r\n", c.uid); if let (Some(last), Some(first)) = (&c.last_name, &c.first_name) { let _ = write!(vcard, "N:{};{};;;\r\n", last, first); } if let Some(fn_name) = &c.full_name { let _ = write!(vcard, "FN:{}\r\n", fn_name); } else { let fn_name = format!( "{} {}", c.first_name.as_deref().unwrap_or(""), c.last_name.as_deref().unwrap_or(""), ) .trim() .to_string(); if !fn_name.is_empty() { let _ = write!(vcard, "FN:{}\r\n", fn_name); } else { vcard.push_str("FN:Unknown\r\n"); } } for (ty, addr) in &c.email { vcard.push_str("EMAIL;TYPE="); oxicloud::common::fmt::push_upper(&mut vcard, ty); vcard.push(':'); vcard.push_str(addr); vcard.push_str("\r\n"); } if let Some(notes) = &c.notes { let _ = write!(vcard, "NOTE:{}\r\n", notes.replace('\n', "\\n")); } let _ = write!(vcard, "REV:{}\r\n", c.updated_at.format("%Y%m%dT%H%M%SZ")); vcard.push_str("END:VCARD\r\n"); vcard } fn v1_after(c: &BenchContact) -> String { let mut vcard = String::with_capacity(256); vcard.push_str("BEGIN:VCARD\r\nVERSION:3.0\r\n"); let _ = write!(vcard, "UID:{}\r\n", c.uid); if let (Some(last), Some(first)) = (&c.last_name, &c.first_name) { let _ = write!(vcard, "N:{};{};;;\r\n", last, first); } if let Some(fn_name) = &c.full_name { let _ = write!(vcard, "FN:{}\r\n", fn_name); } else { let fn_name = format!( "{} {}", c.first_name.as_deref().unwrap_or(""), c.last_name.as_deref().unwrap_or(""), ); let trimmed = fn_name.trim(); if !trimmed.is_empty() { let _ = write!(vcard, "FN:{}\r\n", trimmed); } else { vcard.push_str("FN:Unknown\r\n"); } } for (ty, addr) in &c.email { vcard.push_str("EMAIL;TYPE="); oxicloud::common::fmt::push_upper(&mut vcard, ty); vcard.push(':'); vcard.push_str(addr); vcard.push_str("\r\n"); } if let Some(notes) = &c.notes { if notes.contains('\n') { let _ = write!(vcard, "NOTE:{}\r\n", notes.replace('\n', "\\n")); } else { vcard.push_str("NOTE:"); vcard.push_str(notes); vcard.push_str("\r\n"); } } let mut rev_buf = [0u8; 16]; let secs = c.updated_at.timestamp(); match oxicloud::common::fmt::compact_ical_utc(&mut rev_buf, secs) { Some(s) => { vcard.push_str("REV:"); vcard.push_str(s); vcard.push_str("\r\n"); } None => { let _ = write!(vcard, "REV:{}\r\n", c.updated_at.format("%Y%m%dT%H%M%SZ")); } } vcard.push_str("END:VCARD\r\n"); vcard } fn section_v1() { let iters: usize = env_or("BENCH_ITERS", 200_000); // A contact WITHOUT full_name (exercises the FN fallback), with a // multi-line-free NOTE (the common case) and a REV stamp. let c = BenchContact { uid: "c-round19@oxicloud.test".into(), first_name: Some("Ada".into()), last_name: Some("Lovelace".into()), full_name: None, email: vec![ ("home".into(), "ada@oxicloud.test".into()), ("work".into(), "a.lovelace@work.test".into()), ], notes: Some("Met at the analytical-engine expo; follow up re: punch cards.".into()), updated_at: Utc.timestamp_opt(1_752_753_434, 0).unwrap(), }; let b = v1_before(&c); let a = v1_after(&c); assert_eq!(b, a, "V1 emitted vCard differs between BEFORE and AFTER"); let before = measure(iters, || { black_box(v1_before(black_box(&c))); }); let after = measure(iters, || { black_box(v1_after(black_box(&c))); }); println!("\n## [V1] vCard per-contact emit (FN fallback + NOTE + REV)"); header_footer("contact_to_vcard", &before, &after); gate_allocs("V1", &before, &after); } // ──────────────────────────────────────────────────────────────────────────── // [V2] REV/DTSTAMP stamp — chrono strftime vs compact_ical_utc (wall) // ──────────────────────────────────────────────────────────────────────────── fn section_v2() { let iters: usize = env_or("BENCH_ITERS", 200_000); let dt = Utc.timestamp_opt(1_752_753_434, 0).unwrap(); let secs = dt.timestamp(); // Equivalence: identical stamp bytes. let mut buf = [0u8; 16]; assert_eq!( oxicloud::common::fmt::compact_ical_utc(&mut buf, secs).unwrap(), dt.format("%Y%m%dT%H%M%SZ").to_string(), "V2 stamp differs between chrono and compact_ical_utc" ); // Both write into a reused buffer (isolating the formatter cost, not the // buffer alloc) — mirrors the REV emit into the per-contact vCard buffer. let mut sink = String::with_capacity(32); let before = measure(iters, || { sink.clear(); let _ = write!(sink, "{}", black_box(dt).format("%Y%m%dT%H%M%SZ")); black_box(&sink); }); let after = measure(iters, || { sink.clear(); let mut b = [0u8; 16]; if let Some(s) = oxicloud::common::fmt::compact_ical_utc(&mut b, black_box(secs)) { sink.push_str(s); } black_box(&sink); }); println!("\n## [V2] REV stamp — chrono strftime vs compact_ical_utc"); header_footer("compact_ical_utc", &before, &after); // CPU-only: chrono's DelayedFormat writes field-by-field (no heap), so the // win is wall, not allocs. Require a clear ≥2× to shrug off noise. gate_wall("V2", &before, &after, 2.0); } // ──────────────────────────────────────────────────────────────────────────── // [M4] trash row → DTO — clone vs move of owned String fields // ──────────────────────────────────────────────────────────────────────────── struct BenchTrashRow { resource_id: Uuid, name: String, path: Option, blob_hash: Option, } struct BenchFileDto { id: String, name: String, path: String, content_hash: String, etag: String, } fn compute_etag(hash: &str, modified: u64) -> String { // Same shape as File::compute_etag (a small formatted String) — the point // is the surrounding clone/move, not this helper. format!("\"{hash}-{modified}\"") } fn m4_before(row: BenchTrashRow) -> BenchFileDto { let path = row.path.clone().unwrap_or_default(); let content_hash = row.blob_hash.clone().unwrap_or_default(); let etag = if content_hash.is_empty() { String::new() } else { compute_etag(&content_hash, 1_752_753_434) }; let _classes = row.name.len(); // stands in for classify_display(&row.name, …) BenchFileDto { id: row.resource_id.to_string(), name: row.name.clone(), path, content_hash, etag, } } fn m4_after(row: BenchTrashRow) -> BenchFileDto { let path = row.path.unwrap_or_default(); let content_hash = row.blob_hash.unwrap_or_default(); let etag = if content_hash.is_empty() { String::new() } else { compute_etag(&content_hash, 1_752_753_434) }; let _classes = row.name.len(); BenchFileDto { id: row.resource_id.to_string(), name: row.name, path, content_hash, etag, } } fn make_row() -> BenchTrashRow { BenchTrashRow { resource_id: Uuid::from_u128(0x0e72efc0_0d1c_45a1_b434_52336643b3f7), name: "Quarterly Financial Report 2026 Q3 (final).xlsx".into(), path: Some( "/Documents/Finance/2026/Q3/Quarterly Financial Report 2026 Q3 (final).xlsx".into(), ), blob_hash: Some("af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262".into()), } } fn section_m4() { let iters: usize = env_or("BENCH_ITERS", 200_000); // Equivalence: identical DTO fields. let b = m4_before(make_row()); let a = m4_after(make_row()); assert!( b.id == a.id && b.name == a.name && b.path == a.path && b.content_hash == a.content_hash && b.etag == a.etag, "M4 DTO differs between BEFORE and AFTER" ); let before = measure(iters, || { black_box(m4_before(black_box(make_row()))); }); let after = measure(iters, || { black_box(m4_after(black_box(make_row()))); }); println!("\n## [M4] trash row → DTO (move vs clone)"); // Both arms pay the identical `make_row()` construction + `id.to_string()`; // the delta is the removed name/path/blob_hash clones. header_footer("row_to_item_dto (file branch)", &before, &after); gate_allocs("M4", &before, &after); } // ──────────────────────────────────────────────────────────────────────────── // [M5] search cache key — user_id.to_string() vs stack hyphenated encode // ──────────────────────────────────────────────────────────────────────────── fn m5_key_from_str(user_id: &str) -> u64 { let mut hasher = DefaultHasher::new(); // stand-in for `criteria.hash(&mut hasher)` — a constant, identical both arms "q=report&type=file".hash(&mut hasher); user_id.hash(&mut hasher); hasher.finish() } fn m5_before(user_id: Uuid) -> u64 { let user_id_str = user_id.to_string(); m5_key_from_str(&user_id_str) } fn m5_after(user_id: Uuid) -> u64 { let mut buf = [0u8; uuid::fmt::Hyphenated::LENGTH]; let s = user_id.hyphenated().encode_lower(&mut buf); m5_key_from_str(s) } fn section_m5() { let iters: usize = env_or("BENCH_ITERS", 200_000); let user_id = Uuid::from_u128(0xc410b103_7b86_4ac2_9eb4_3804351547be); // Equivalence: the stack-encoded string is byte-identical to to_string(), // so the hasher sees identical bytes ⇒ identical key. assert_eq!( m5_before(user_id), m5_after(user_id), "M5 cache key differs between BEFORE and AFTER" ); let before = measure(iters, || { black_box(m5_before(black_box(user_id))); }); let after = measure(iters, || { black_box(m5_after(black_box(user_id))); }); println!("\n## [M5] search cache key (Uuid stack-encode)"); header_footer("create_cache_key user segment", &before, &after); gate_allocs("M5", &before, &after); } // ──────────────────────────────────────────────────────────────────────────── // [M6] PROPFIND per-child href — fresh format! vs reused buffer // ──────────────────────────────────────────────────────────────────────────── const BENCH_ENCODE_SET: &AsciiSet = NON_ALPHANUMERIC; fn m6_before(base_href: &str, names: &[String]) -> usize { // Mirrors the shipped per-child loop: one fresh String per row. let mut total = 0usize; for name in names { let href = format!( "{}{}", base_href, utf8_percent_encode(name, BENCH_ENCODE_SET) ); total += black_box(href).len(); } total } fn m6_after(base_href: &str, names: &[String]) -> usize { // One buffer reused across the whole page. let mut total = 0usize; let mut href = String::new(); for name in names { href.clear(); href.push_str(base_href); href.extend(utf8_percent_encode(name, BENCH_ENCODE_SET)); total += black_box(&href).len(); } total } fn section_m6() { let iters: usize = env_or("BENCH_ITERS", 4_000); // per-op is a whole page let base_href = "/webdav/Documents/Projects/"; let names: Vec = (0..64) .map(|i| format!("Report {i} draft (v2) — final.pdf")) .collect(); // Equivalence: byte-identical href set. let mut hb = Vec::new(); for name in &names { hb.push(format!( "{}{}", base_href, utf8_percent_encode(name, BENCH_ENCODE_SET) )); } let mut ha = Vec::new(); { let mut href = String::new(); for name in &names { href.clear(); href.push_str(base_href); href.extend(utf8_percent_encode(name, BENCH_ENCODE_SET)); ha.push(href.clone()); } } assert_eq!(hb, ha, "M6 href set differs between BEFORE and AFTER"); let before = measure(iters, || { black_box(m6_before(black_box(base_href), black_box(&names))); }); let after = measure(iters, || { black_box(m6_after(black_box(base_href), black_box(&names))); }); println!( "\n## [M6] PROPFIND per-child href ({}-child page, reused buffer)", names.len() ); header_footer("streaming PROPFIND href build", &before, &after); gate_allocs("M6", &before, &after); } // ──────────────────────────────────────────────────────────────────────────── // [M7] NC extract_url_user — into_owned() vs Cow // ──────────────────────────────────────────────────────────────────────────── fn m7_before(user_seg: &str, raw_username: &str) -> bool { // Shipped-before: force an owned String, then compare. match urlencoding::decode(user_seg).ok().map(|s| s.into_owned()) { Some(url_user) => url_user != raw_username, None => false, } } fn m7_after(user_seg: &str, raw_username: &str) -> bool { // Shipped-after: keep the Cow, compare by slice (zero-alloc on the common // no-escape path). match urlencoding::decode(user_seg).ok() { Some(url_user) => url_user.as_ref() != raw_username, None => false, } } fn section_m7() { let iters: usize = env_or("BENCH_ITERS", 200_000); let user_seg = "benchuser"; // plain ASCII, decodes to Cow::Borrowed let raw_username = "benchuser"; // Equivalence: same mismatch verdict (here: equal ⇒ false). assert_eq!( m7_before(user_seg, raw_username), m7_after(user_seg, raw_username), "M7 verdict differs between BEFORE and AFTER" ); // And on a genuine mismatch. assert_eq!( m7_before("someone", raw_username), m7_after("someone", raw_username), "M7 mismatch verdict differs between BEFORE and AFTER" ); let before = measure(iters, || { black_box(m7_before(black_box(user_seg), black_box(raw_username))); }); let after = measure(iters, || { black_box(m7_after(black_box(user_seg), black_box(raw_username))); }); println!("\n## [M7] NC extract_url_user (Cow, no into_owned)"); header_footer("path-scoped NC user cross-check", &before, &after); gate_allocs("M7", &before, &after); } fn main() { println!("#################################################################"); println!("# Round-19 CPU/alloc micro-pack (no Postgres)"); println!("#################################################################"); section_m1(); section_m2(); section_v1(); section_v2(); section_m4(); section_m5(); section_m6(); section_m7(); println!("\nGATE PASS (all sections)"); }