pub struct Store {
pub issues_dir: PathBuf,
pub config: Config,
}Fields§
§issues_dir: PathBuf§config: ConfigImplementations§
Source§impl Store
impl Store
pub fn open(config: &Config) -> Result<Store>
pub fn list(&self) -> Result<Vec<Issue>>
pub fn get(&self, selector: IssueSelector) -> Result<Issue>
Sourcepub fn create(
&self,
issue: &mut Issue,
body: &str,
filename_stem: Option<&str>,
) -> Result<PathBuf>
pub fn create( &self, issue: &mut Issue, body: &str, filename_stem: Option<&str>, ) -> Result<PathBuf>
Create an issue file atomically and assign its number by scanning the
live issue set (issue #52): the highest existing number plus one,
with a floor of 0 for an empty store.
The number is resolved at creation time rather than read from a
persisted [state].next_number counter, so tix.toml is never
rewritten by create. A deleted high-numbered issue’s number can be
reused by a later create; the frontmatter number stays stable for
every surviving issue (C-007).
The file is written into the assignee segment derived from
issue.assignee (unassigned/ fallback, FR-029/FR-030), creating the
segment directory as needed, and issue.filename is set to the
relative path so create output and later edits agree. Atomic-write
discipline (temp + rename, NFR-006) is preserved.
pub fn config_path(&self) -> Result<PathBuf>
pub fn update(&self, filename: &str, issue: &Issue) -> Result<()>
Sourcepub fn add_asset(
&self,
filename: &str,
source_path: &Path,
) -> Result<AssetAdded>
pub fn add_asset( &self, filename: &str, source_path: &Path, ) -> Result<AssetAdded>
Copy an asset into the issue’s <slug>-assets/ directory (FR-006) and
insert a relative markdown link at the end of the body, persisted via
Store::update (NFR-004).
The asset dir is derived from the issue filename per
contracts/comments-format.md: <slug>-assets/ where <slug> is the
basename stem minus the leading YYYY-MM-DD- date prefix. The copy is
atomic (temp + rename, NFR-004); on a name collision the file is stored
as <stem>-<n>.<ext> (first free n) and the inserted link points at
the actual written name. Image extensions (.png .jpg .jpeg
.gif .svg .webp .bmp) get the  form, everything else
the […](…) form. The link path is relative to the issue file, so the
segment prefix is never part of it.
pub fn delete(&self, filename: &str) -> Result<()>
pub fn set_status(&self, filename: &str, new_status: &str) -> Result<Issue>
Sourcepub fn link(&self, a: &str, b: &str) -> Result<(Issue, Issue)>
pub fn link(&self, a: &str, b: &str) -> Result<(Issue, Issue)>
Symmetrically link two issues by their selectors (D2).
Both selectors are resolved with the same grammar and errors as the
selector-taking commands (tix edit/tix move, parse_selector);
linking an issue to itself is InvalidInput. The two identifiers are
number-based, so self-links are detected by comparing resolved numbers.
Each issue gains the other’s number in its links list if absent
(idempotent). Both files are written atomically with updated bumped.
Sourcepub fn unlink(&self, a: &str, b: &str) -> Result<(Issue, Issue)>
pub fn unlink(&self, a: &str, b: &str) -> Result<(Issue, Issue)>
Symmetrically remove the link between two issues (D2).
Both selectors are resolved like Store::link. Removing a pair that
was never linked is a no-op: neither file is written. Each issue drops
the other’s number from its links list and gets updated bumped when
something actually changed.
Sourcepub fn set_links(&self, filename: &str, new: Vec<u32>) -> Result<Issue>
pub fn set_links(&self, filename: &str, new: Vec<u32>) -> Result<Issue>
Replace one issue’s links list and reconcile back-references (D2).
Only numeric targets are accepted; every referenced number must already
exist (NotFound otherwise) and a self-link is InvalidInput. Numbers
newly added get this issue’s number appended to their links; numbers
dropped have it removed. Each touched issue is written exactly once with
updated bumped; the target issue itself always wins on the default
non-numeric tolerance (hand-edited values untouched by this path).
Sourcepub fn reassign(
&self,
filename: &str,
new_assignee: Option<&str>,
) -> Result<PathBuf>
pub fn reassign( &self, filename: &str, new_assignee: Option<&str>, ) -> Result<PathBuf>
Physically move an issue file into the assignee segment of a new
assignee (FR-031, contracts/file-format.md rule 9).
filename is a path relative to the issues dir: either a legacy flat
basename (2026-05-10-fix-login.md, C-010) or a grouped path
(alice/2026-05-10-fix-login.md). It is validated via the relaxed
[validate_filename] before anything touches the filesystem, so
traversal attempts are refused here as everywhere else.
The old assignee segment is read from the current relative path, the
new one derived with derive_segment; equal segments are a no-op.
The target filename keeps the original created-slug stem; when the
target already holds <stem>.md, a deterministic -1, -2, …
suffix is appended by testing existence — an existing file is never
overwritten or deleted. number/created live in the frontmatter and
are untouched, so issue-number stability is guaranteed by construction
(C-007).
The move is a single std::fs::rename (atomic-ish, same filesystem).
Returns the new relative path (matching how issue.filename is
stored) on success, including the unchanged relative path for the
equal-segment no-op.
Auto Trait Implementations§
impl Freeze for Store
impl RefUnwindSafe for Store
impl Send for Store
impl Sync for Store
impl Unpin for Store
impl UnsafeUnpin for Store
impl UnwindSafe for Store
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
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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