Skip to main content

ProjectConfig

Struct ProjectConfig 

Source
pub struct ProjectConfig {
Show 14 fields pub dialect: Option<Dialect>, pub types: Option<TypePolicy>, pub lints: BTreeMap<String, LintLevel>, pub deny_warnings: Option<bool>, pub fix: BTreeMap<String, FixPolicy>, pub unprune_dirs: Vec<String>, pub indent: Option<u8>, pub drafts: Vec<String>, pub prose_dialect: Option<ProseDialect>, pub prose_enable: Option<bool>, pub prose_dictionary: Vec<String>, pub conventions: Option<String>, pub dialogue: Option<DialogueConfig>, pub entry: Option<String>,
}

Fields§

§dialect: Option<Dialect>

[project] dialect, if set.

§types: Option<TypePolicy>

[project] types, if set.

§lints: BTreeMap<String, LintLevel>

[lints] per-code severity overrides, keyed by the raw code string as written in the file (e.g. "E063") — this crate doesn’t validate codes against the real DiagnosticCode set (#1234 dependency-free constraint); resolving unknown/non-overridable codes is brink-analyzer’s job. Sorted (BTreeMap) for deterministic iteration.

§deny_warnings: Option<bool>

[lints] deny-warnings, if set.

§fix: BTreeMap<String, FixPolicy>

[fix] per-code policy overrides (docs/autofix-spec.md §6.1, issue #3419), keyed by the raw code string as written in the file — this crate doesn’t validate codes against the real DiagnosticCode set, same as Self::lints. A code absent from this map resolves to FixPolicy::Ask via Self::effective_fix_policy, never to a default invented at the call site. Sorted (BTreeMap) for deterministic iteration.

§unprune_dirs: Vec<String>

[project] unprune-dirs, if set: directory names discovery must not prune, layered on top of the standing brink_source_tree::IGNORED_DIR_NAMES policy (issue #1407’s escape hatch). Empty (the default) means “the standing policy applies with no override” — same “unset means untouched” convention as lints. Raw strings as written in the file; a name outside brink_source_tree::IGNORED_DIR_NAMES parses fine (this crate stays dependency-free of anything beyond brink_source_tree, and there is nothing wrong in principle with naming a directory that isn’t pruned in the first place) but is a no-op, so parse_str_at warns about it rather than silently accepting a likely typo (e.g. "node-modules" instead of "node_modules").

§indent: Option<u8>

[project] indent, if set: the number of spaces one indent level occupies. THE single source for indentation across the project (decision log 2026-08-27) — the formatter emits it, the editor’s indentUnit adopts it, and the indent guides position against it. No component may keep its own default, because the failure mode is disagreement: a formatter writing four spaces while guides are drawn every two looks like a rendering glitch rather than a config mismatch, and the author cannot tell which component is wrong.

None means unset — callers apply DEFAULT_INDENT.

§drafts: Vec<String>

[project] drafts, if set: path globs (see globs) naming work-in-progress the author has deliberately not wired into the story — scratch scenes, cut material, notes.

A match here is only HALF of draft status. Ruled 2026-08-27 (“reachability wins”): a file is a draft when it matches one of these globs and is not reachable from the entry. A marked file the entry still INCLUDEs is not a draft at all — it compiles normally. That is deliberately a deleted state rather than a diagnosed one: draft status can then never exclude a file the story actually reaches, so it can never break a divert. This crate carries only the glob half, because reachability is the compile closure’s answer and lives in the analysis roads; see EditorSession::draft_paths for the conjunction.

Empty (the default) means no file is ever a draft.

§prose_dialect: Option<ProseDialect>

[prose] dialect, if set. None means unset — callers apply ProseDialect::default.

§prose_enable: Option<bool>

[prose] enable, if set: whether prose checking runs at all.

Its own key rather than “unregister the checker”, because those are different decisions by different people: an embedder decides whether the engine is available at all (it is a separate 6.5 MB module), and this decides whether a project that has it wants its prose checked. None means unset — callers apply their own default.

§prose_dictionary: Vec<String>

[prose] dictionary — the author’s own word list: place names, in-world jargon, a character who is never a cue.

In brink.toml rather than a sidecar because a character’s name is a fact about the manuscript, not about one machine — so it is shared by collaborators and survives a fresh clone (decision log, “Spellcheck: prose only, squiggles always, dictionary in brink.toml”).

Empty and absent are the same thing here, unlike the two options above: there is no behaviour a project could want from “declared but empty” that it does not get from “absent”.

§conventions: Option<String>

[project] conventions, if set (docs/prose-dialect-spec.md §3.4’s pointer mechanism): either a built-in preset name ("screenplay") or a project-relative path to a .brink conventions module ("conventions.brink", "scenes/conventions.brink"). This crate only carries the raw string — it doesn’t know the closed preset-name set or validate the path exists, for the same dependency-free reason lints doesn’t validate codes (#1234); resolving it (and, if it names a project path, checking that pattern-claiming handlers only live in that one file, issue #1844’s confinement rule) is brink-analyzer/brink-db’s job.

Renamed from elements by issue #2180 (the key predates the split of @[element] from @[convention], docs/decision-log.md’s 2026-08-03 ruling, and now names a module of the latter, not the former). parse_str_at still accepts the old [project] elements spelling as a deprecated alias — see its own doc comment for the precedence/warning rules — but every in-memory representation past parsing uses only this field; there is no separate elements field to keep in sync.

§dialogue: Option<DialogueConfig>

[dialogue] (or the string form dialogue = "path.json"), if the file declares one — see DialogueConfig. None = no dialect.

§entry: Option<String>

[project] entry, if set (issue #2331, ruled 2026-08-07 “[project] entry beats mountStudio’s entryFile”): a project-relative path naming the project’s entry file (e.g. "story.ink", "chapters/main.brink"). Same shape as Self::conventions — this crate only carries the raw string, without checking the path exists or resolving it against a real project tree (kept dependency-free, #1234); that is each mount’s own job (e.g. ProjectSession in packages/ink-editor/src/project-session.ts, which knows the project’s actual file set).

The ruling: when both this key and a host’s own entry-file argument are present, this key WINS — the host argument is only the fallback for a configless project (one with no brink.toml, or a brink.toml that doesn’t set entry). Unlike dialect/types, there is no “explicit API call always wins” precedence tier here: the host argument was never an explicit override API in the first place, just a constructor-time default that had nowhere better to come from before this field existed.

Implementations§

Source§

impl ProjectConfig

Source

pub fn is_empty(&self) -> bool

True if the file set nothing at all (an all-default/empty [project]/[lints] table, or neither table present).

Source

pub fn effective_fix_policy( &self, code: &str, app_ceiling: Option<FixPolicy>, ) -> FixPolicy

The effective [fix] policy for code (docs/autofix-spec.md §6, issue #3419): the project’s own [fix] entry (or FixPolicy::Ask when it doesn’t mention code), narrowed by an optional app-scope app_ceiling (§6.2, TENTATIVE ruling) — a personal “how far may the editor go on save” setting the host passes in, kept in the same FixPolicy space.

app_ceiling only LOWERS the result, never raises it past what the project allows: None means “no app opinion”, so the project entry alone decides. This is the one function §6.2 asks to keep singular so the still-tentative ceiling relationship can change in one place.

This crate doesn’t validate code against the real DiagnosticCode set (dependency-free, #1234, same split as Self::lints) — an unknown code resolves through the same default/ceiling math as a real one here; surfacing “this code doesn’t exist” as a diagnostic is a downstream crate’s job, the same as [lints]’s validate_lint_code.

Trait Implementations§

Source§

impl Clone for ProjectConfig

Source§

fn clone(&self) -> ProjectConfig

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 ProjectConfig

Source§

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

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

impl Default for ProjectConfig

Source§

fn default() -> ProjectConfig

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

impl Eq for ProjectConfig

Source§

impl PartialEq for ProjectConfig

Source§

fn eq(&self, other: &ProjectConfig) -> 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 ProjectConfig

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

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

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

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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 = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more