Skip to main content

NormalizeTable

Struct NormalizeTable 

Source
pub struct NormalizeTable { /* private fields */ }
Expand description

The normalized plans for one parsed source tree.

Keyed by the binding-group node’s text_range().start(), exactly as sui_resolve::ResolveTable keys idents. An unrecorded offset means the group needs no normalization — no duplicate static key and no dotted path — so consumers keep their existing path for it.

Implementations§

Source§

impl NormalizeTable

Source

pub fn new() -> Self

An empty table — every lookup returns None.

Source

pub fn get(&self, text_offset: u32) -> Option<&GroupPlan>

The plan recorded for the group node starting at text_offset, if any.

Source

pub fn len(&self) -> usize

Number of recorded groups. Small by construction — see the module docs.

Examples found in repository?
examples/scan.rs (line 80)
49fn main() {
50    let roots: Vec<PathBuf> = std::env::args().skip(1).map(PathBuf::from).collect();
51    if roots.is_empty() {
52        eprintln!("usage: scan <dir> [<dir>…]");
53        std::process::exit(2);
54    }
55
56    let mut files = Vec::new();
57    for r in &roots {
58        nix_files(r, &mut files);
59    }
60
61    let (mut unparseable, mut clean, mut planned, mut rejected) = (0usize, 0usize, 0usize, 0usize);
62    let mut groups = 0usize;
63    let mut rejects: Vec<(PathBuf, String)> = Vec::new();
64
65    for f in &files {
66        let Ok(src) = std::fs::read_to_string(f) else {
67            continue;
68        };
69        let parse = rnix::Root::parse(&src);
70        if !parse.errors().is_empty() {
71            // rnix could not parse it — not this pass's business, and counted
72            // separately so it can never be mistaken for a clean result.
73            unparseable += 1;
74            continue;
75        }
76        match sui_normalize::normalize(&parse.tree()) {
77            Ok(table) if table.is_empty() => clean += 1,
78            Ok(table) => {
79                planned += 1;
80                groups += table.len();
81            }
82            Err(e) => {
83                rejected += 1;
84                rejects.push((f.clone(), e.to_string()));
85            }
86        }
87    }
88
89    println!("scanned    {}", files.len());
90    println!("  clean      {clean}   (no duplicate key, no dotted path — untouched)");
91    println!("  planned    {planned}   ({groups} binding groups — THE BLAST RADIUS)");
92    println!("  rejected   {rejected}   (must be 0 before the rejection tier flips)");
93    println!("  unparseable {unparseable}   (rnix could not read; not this pass's business)");
94
95    for (p, e) in rejects.iter().take(25) {
96        println!("  REJECT {}: {e}", p.display());
97    }
98    if rejects.len() > 25 {
99        println!("  … and {} more", rejects.len() - 25);
100    }
101}
Source

pub fn is_empty(&self) -> bool

True when no group needed normalization.

Examples found in repository?
examples/scan.rs (line 77)
49fn main() {
50    let roots: Vec<PathBuf> = std::env::args().skip(1).map(PathBuf::from).collect();
51    if roots.is_empty() {
52        eprintln!("usage: scan <dir> [<dir>…]");
53        std::process::exit(2);
54    }
55
56    let mut files = Vec::new();
57    for r in &roots {
58        nix_files(r, &mut files);
59    }
60
61    let (mut unparseable, mut clean, mut planned, mut rejected) = (0usize, 0usize, 0usize, 0usize);
62    let mut groups = 0usize;
63    let mut rejects: Vec<(PathBuf, String)> = Vec::new();
64
65    for f in &files {
66        let Ok(src) = std::fs::read_to_string(f) else {
67            continue;
68        };
69        let parse = rnix::Root::parse(&src);
70        if !parse.errors().is_empty() {
71            // rnix could not parse it — not this pass's business, and counted
72            // separately so it can never be mistaken for a clean result.
73            unparseable += 1;
74            continue;
75        }
76        match sui_normalize::normalize(&parse.tree()) {
77            Ok(table) if table.is_empty() => clean += 1,
78            Ok(table) => {
79                planned += 1;
80                groups += table.len();
81            }
82            Err(e) => {
83                rejected += 1;
84                rejects.push((f.clone(), e.to_string()));
85            }
86        }
87    }
88
89    println!("scanned    {}", files.len());
90    println!("  clean      {clean}   (no duplicate key, no dotted path — untouched)");
91    println!("  planned    {planned}   ({groups} binding groups — THE BLAST RADIUS)");
92    println!("  rejected   {rejected}   (must be 0 before the rejection tier flips)");
93    println!("  unparseable {unparseable}   (rnix could not read; not this pass's business)");
94
95    for (p, e) in rejects.iter().take(25) {
96        println!("  REJECT {}: {e}", p.display());
97    }
98    if rejects.len() > 25 {
99        println!("  … and {} more", rejects.len() - 25);
100    }
101}
Source

pub fn iter(&self) -> impl Iterator<Item = (u32, &GroupPlan)>

Iterate the recorded (text_offset, plan) pairs. Consumers merge these into their own per-(source_id, offset) table, exactly as sui-resolve’s consumers do.

Trait Implementations§

Source§

impl Clone for NormalizeTable

Source§

fn clone(&self) -> NormalizeTable

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for NormalizeTable

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for NormalizeTable

Source§

fn default() -> NormalizeTable

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.