Skip to main content

ComponentRule

Struct ComponentRule 

Source
pub struct ComponentRule {
    pub path: PathBuf,
    pub index: u32,
    pub options: String,
    pub bytes: ComponentBytes,
    pub source_map: Option<ComponentBytes>,
    /* private fields */
}
Expand description

Where a component-backed rule’s code is, and what it is configured with.

One value rather than two fields, because the two cannot be independently true. A rule backed by a component is always configured — with null when the config named it with no options, which is the shape crates/lanekeep-wasm/wit/world.wit declares so that a guest has one code path rather than two — and a rule that is not backed by a component has no configure to reach. Splitting them would make “a component with nothing to configure it with” and “options belonging to no component” representable, and both are states nothing downstream knows what to do with.

Fields§

§path: PathBuf

Where the bytes came from: a path confined to the rules root, or lanekeep/<name> for a built-in embedded in the binary.

Kept for diagnostics and for the order ComponentBytes are folded into ruleset_hash in. Nothing reads the file again — see ComponentRule::bytes.

A built-in’s is a specifier rather than a path, and cannot collide with one. A confined path is absolute, because RuleRoot::confine canonicalizes; lanekeep/no-unwrap is relative. So a project that happens to have lanekeep/no-unwrap.wasm inside its rules root sorts and dedups separately, as two different rules should.

§index: u32

Which of the component’s rules this is: an index into what its rules export lists.

A component hosts a list, so naming one is a position and not merely a file. Every export but rules takes this index, so it is what tells configure, metadata, check and reduce which rule they are being asked about. A component hosting one rule is 0, which is what every reference resolved to before a component could host more than one.

It is folded into ruleset_hash beside the component’s identity rather than being carried only for execution: two rules of one component share every byte of code, so the index is the whole of what distinguishes the programs they run. Without it, “rule 0 and rule 1 of this component” and “rule 0 of this component, twice” are one cache key.

§options: String

What configure is called with, as JSON — "null" for a rule named with no options.

A string rather than a serde_json::Value because that is what crosses the boundary: a component cannot close over a host-supplied value the way a JavaScript factory does, so its options arrive as data. Serializing once here also fixes the bytes, which matters because they are what every worker’s configure is handed.

§bytes: ComponentBytes

The component itself, read exactly once.

The rule that was described has to be the rule that runs. The bytes used to be read three times in a run — once to ask the component what it is, once to hash it, once to execute it — and a file that changed between those reads would give metadata from one, a cache key from a second and handlers from a third, with nothing to notice. That is the same property the TypeScript path already has for free: hash_ruleset folds what RuleLoader actually consumed, not a second read of the same paths.

So they are read once, here, and carried: metadata is read from them, ruleset_hash folds them, and lanekeep-engine loads the component from them rather than from the path beside them.

Behind an std::sync::Arc, because a RuleSpec is cloned per rule when the engine prepares and a per-rule copy of a megabyte is a cost with nothing to buy it.

§source_map: Option<ComponentBytes>

The component’s sidecar source map, or None for one that ships without one.

Carried beside the bytes for the same reason they are carried at all: the component that was described has to be the component that runs, and the map is only correct for the bundle it was generated from. Reading it a second time later, from a path, would let a file that changed in between explain the positions of a program it does not describe.

Not a ruleset_hash input, and that is a decision rather than an omission. A map changes exactly one thing: where a thrown rule error is reported. It cannot move a violation — a violation’s position comes from the parse tree by way of a node handle — and every failure it touches cancels the run, so no cache entry is ever written by a run whose output it affected. Two runs differing only in their maps produce byte-identical output for every file that completes.

Implementations§

Source§

impl ComponentRule

Source

pub const fn counted_in_ruleset_hash(&self) -> bool

Whether these bytes are folded into the ruleset_hash of the Config they arrived with — see the field.

Source

pub fn uncounted( path: PathBuf, index: u32, options: String, bytes: impl Into<ComponentBytes>, ) -> Self

Build a ComponentRule outside lanekeep_config::load.

Whatever this produces is not folded into any Config’s ruleset_hash, because nothing here computes one — that happens exactly once, inside load, over whichever rules were in Config.rules at the moment it returned. This is for an embedder, or a test, that attaches a component to a RuleSpec afterward: lanekeep-engine’s own component tests are exactly that, which is why Engine::caching refuses the cache for a run carrying one of these.

Trait Implementations§

Source§

impl Clone for ComponentRule

Source§

fn clone(&self) -> ComponentRule

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 ComponentRule

Source§

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

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

impl Eq for ComponentRule

Source§

impl PartialEq for ComponentRule

Source§

fn eq(&self, other: &ComponentRule) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for ComponentRule

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<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ParallelSend for T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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 = !

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.