Skip to main content

Engine

Struct Engine 

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

The sources a configuration resolved to, and the queries they answer.

Implementations§

Source§

impl Engine

Source

pub async fn task_detail( &self, id: &GlobalId, ) -> Result<TaskDetail, EngineError>

One task by its qualified id, with its comments when its source has them.

The task is read exactly as task reads it, and the comments are read only once the task was found — a source declaring no comments is never asked. Both halves go through the source’s one get_task_details call, so a source that reads an item and its first page of comments in one request answers in one.

§Errors

As task. A comment read that fails is not an error: it lands in the response’s errors beside the task that was read.

Source

pub async fn task_details( &self, ids: &[GlobalId], comments: bool, ) -> TaskDetails

Several tasks by their qualified ids, each with its comments when comments is set and its source has them — the ids may span sources.

Each source is asked once, for every id naming it, through its get_task_details; what each detail holds is what task_detail, or task when comments is unset, answers for that id. An id that answer would refuse — it names no configured source — or answer with nothing — its source holds no such task — carries that in its own detail’s errors, so one unreadable id never refuses the others, and a caller reads every failure from the same place.

Source

pub async fn task_without_comments( &self, id: &GlobalId, ) -> Result<TaskDetail, EngineError>

One task by its qualified id with its image assets beside it, and without its comments — what task show --no-comments answers with.

§Errors

As task.

Source

pub async fn document_detail( &self, id: &GlobalId, ) -> Result<DocumentDetail, EngineError>

One document by its qualified id with its image assets beside it: what document show answers with.

§Errors

As document.

Source

pub async fn comments( &self, task: &GlobalId, ) -> Result<CommentList, EngineError>

Every comment on one task, oldest first.

§Errors

Returns EngineError::NoComments for a source whose tasks have none, before anything is read; EngineError::NoSuchTask when the source holds no such task; and EngineError::SourceFailed when the source could not answer.

Source

pub async fn add_comment( &self, task: &GlobalId, comment: &NewComment, ) -> Result<Comment, EngineError>

Add one comment to a task, answering with the comment as its source now holds it.

§Errors

As comments, plus EngineError::CommentsNotWritable for a source whose comments cannot be written, before anything is written.

Source

pub async fn edit_comment( &self, task: &GlobalId, comment: &NativeId, body: &CommentBody, ) -> Result<Comment, EngineError>

Replace one comment’s body, answering with the comment as its source now holds it.

§Errors

As add_comment, plus EngineError::NoSuchComment when the task has no comment under comment.

Source

pub async fn delete_comment( &self, task: &GlobalId, comment: &NativeId, ) -> Result<DeletedComment, EngineError>

Remove one comment from a task, answering with the id it removed.

§Errors

As edit_comment.

Source§

impl Engine

Source

pub async fn copy( &self, request: &CopyRequest, ) -> Result<CopyReport, EngineError>

Copy every item a request names into one configured destination.

This is the whole of the verb, and the command line drives exactly this: a copy a Rust caller makes and a copy typed at a shell are the same call, so the two cannot answer the same copy differently.

§Errors

Returns EngineError when the destination is not configured, cannot be built, cannot be written, or — for a document copy — declares it has no documents; when an id names nothing; when an origin names an item the destination no longer holds and --recreate was not given; and when the destination refuses the write — including a field or a metadata key it cannot carry, which it names rather than dropping.

Source§

impl Engine

Source

pub async fn set_task_status( &self, id: &GlobalId, category: StatusCategory, ) -> Result<TaskStatusSet, EngineError>

Set one task’s status, and nothing else about it, then keep every task it delivers in step with it.

§Errors

Returns EngineError::UnknownSource for a source nothing configures, EngineError::StatusNotWritable for one with no write side, EngineError::NoSuchTask when the task is not there, and EngineError::SourceFailed when the source refuses — a category it has disabled included. A delivered task that cannot be kept in step is not an error: it is reported failed beside the status that was set.

Source§

impl Engine

Source

pub async fn set_task_metadata( &self, id: &GlobalId, key: &MetadataKey, value: &Value, ) -> Result<MetadataSet, EngineError>

Set one key of one task’s metadata, and nothing else about it.

§Errors

Returns EngineError::UnknownSource for a source nothing configures, EngineError::MetadataNotWritable for one with no write side, EngineError::NoSuchTask when the task is not there, and EngineError::SourceFailed when the source refuses — a plugin that cannot write one key on its own included.

Source

pub async fn set_project_metadata( &self, id: &GlobalId, key: &MetadataKey, value: &Value, ) -> Result<MetadataSet, EngineError>

Set one key of one project’s metadata, and nothing else about it.

§Errors

As set_task_metadata, with EngineError::NoSuchProject when the project is not there.

Source

pub async fn set_document_metadata( &self, id: &GlobalId, key: &MetadataKey, value: &Value, ) -> Result<MetadataSet, EngineError>

Set one key of one document’s metadata, and nothing else about it.

§Errors

As set_task_metadata, with EngineError::NoDocuments for a source declaring it has none — which is never asked — and EngineError::NoSuchDocument when the document is not there.

Source§

impl Engine

Source

pub async fn set_task_priority( &self, id: &GlobalId, priority: Priority, ) -> Result<TaskPrioritySet, EngineError>

Set one task’s priority, and nothing else about it.

§Errors

Returns EngineError::UnknownSource for a source nothing configures, EngineError::PriorityNotWritable for one with no write side, EngineError::NoPriority for one declaring it holds no priority — neither of which is asked — EngineError::NoSuchTask when the task is not there, and EngineError::SourceFailed when the source refuses, a board with no option for the priority included.

Source

pub async fn set_task_content( &self, id: &GlobalId, content: &str, ) -> Result<TaskContentSet, EngineError>

Replace one task’s content with content, byte for byte, and nothing else about it.

§Errors

Returns EngineError::UnknownSource for a source nothing configures, EngineError::ContentNotWritable for one with no write side, which is not asked, EngineError::NoSuchTask when the task is not there, and EngineError::SourceFailed when the source refuses.

Source§

impl Engine

Source

pub async fn create_task( &self, request: &TaskCreate, ) -> Result<TaskCreated, EngineError>

Create one task, from a plain body or a template’s rendering, and keep every task it delivers in step with it.

The content, the provenance and — where the source keeps them — the answers land in one write. A delivered task that cannot be kept in step is not an error: it is reported failed beside the task that was created.

§Errors

EngineError::UnknownSource and EngineError::SourceUnavailable for a source that cannot be reached, EngineError::NotCreatable for one with no write side — neither is written — and EngineError::SourceFailed when the source refuses the task.

Source

pub async fn create_document( &self, request: &DocumentCreate, ) -> Result<Qualified<Document>, EngineError>

Create one project document, or replace the one the source holds under DocumentCreate::id, from a plain body or a template’s rendering.

§Errors

As create_task, and EngineError::NoDocuments for a source declaring it has none, which is not asked.

Source

pub async fn create_project( &self, request: &ProjectCreate, ) -> Result<Qualified<Project>, EngineError>

Create one project, or replace the one the source holds under ProjectCreate::id, from a plain body or a template’s rendering.

A replacement lands the content, the provenance and — where the source keeps them — the answers whole, as a create does, and writes back what the project holds otherwise: its status, labels and repositories unless the request names them, every metadata key the request does not set, and its dependencies. A plain body records no provenance, so it takes away the entry a rendering recorded.

§Errors

EngineError::UnknownSource and EngineError::SourceUnavailable for a source that cannot be reached, EngineError::NotCreatable for one with no write side — neither is written — and EngineError::SourceFailed when the source refuses the project.

Source

pub async fn template_answers( &self, record: RenderedRecord, id: &GlobalId, ) -> Result<TemplateAnswers, EngineError>

The answers the task, project or document id was last rendered from, as its source keeps them.

§Errors

EngineError::NoSuchTask, EngineError::NoSuchProject or EngineError::NoSuchDocument when the item is not there, EngineError::NoStoredAnswers naming it when none are stored for it — which is every item of a source that keeps none — and EngineError::SourceFailed when the source cannot answer.

Source

pub async fn regeneration( &self, record: RenderedRecord, id: &GlobalId, request: &RenderRequest, ) -> Result<Regeneration, EngineError>

Read everything a regenerate of the task, project or document id needs, before it renders.

§Errors

EngineError::NoSuchTask, EngineError::NoSuchProject or EngineError::NoSuchDocument when the item is not there; EngineError::NoTemplate when no template is given and the item records none; EngineError::MalformedProvenance when no template is given and the entry it records is not one this product writes; EngineError::TemplateNotAFile when no template is given and the one it records is not a readable file, which only a loader document can then stand in for; EngineError::Template when the template cannot be loaded; and the refusals of a source that cannot be reached or cannot answer.

Source

pub async fn regenerate( &self, regeneration: &Regeneration, answers: &Answers, dry_run: bool, ) -> Result<Regenerated, EngineError>

Render regeneration with answers laid over its base, and write the content, the provenance and the answers in one write — and nothing else about the item — when any of them differs from what it holds and this is not a dry run.

§Errors

Every refusal of Regeneration::render; EngineError::RenderingNotWritable for a source with no write side, which is not asked; and EngineError::SourceFailed when the source refuses the write.

Source

pub async fn render_task( &self, id: &GlobalId, request: &RenderRequest, ) -> Result<Regenerated, EngineError>

Regenerate one task in place: regeneration then regenerate, never asking for an answer.

§Errors

Every refusal of either half.

Source

pub async fn render_project( &self, id: &GlobalId, request: &RenderRequest, ) -> Result<Regenerated, EngineError>

Regenerate one project in place, on the terms of render_task: its content, its provenance and its stored answers, and nothing else about it.

§Errors

As render_task.

Source

pub async fn render_document( &self, id: &GlobalId, request: &RenderRequest, ) -> Result<Regenerated, EngineError>

Regenerate one project document in place, on the terms of render_task.

§Errors

As render_task.

Source§

impl Engine

Source

pub async fn update_task( &self, id: &GlobalId, update: &TaskUpdate, ) -> Result<TaskUpdated, EngineError>

Apply a targeted update to one task — every field update names, and nothing else — then keep every task it delivers in step with it when status or delivers was named.

The source is asked once, and nothing else of it is read: a field already holding the requested value is sent no write, and an update in which nothing differs writes nothing at all — an update naming no field included, which answers the task as its source reads it and re-evaluates nothing; the CLI refuses that one as a usage error before it gets here, a library caller is answered. update.depends_on may name its far ends qualified; one in this task’s own source reaches the source as its native id, and each edge’s from is this task.

§Errors

Returns EngineError::UnknownSource for a source nothing configures, EngineError::UpdateNotWritable for one with no write side, EngineError::NoPriority for a priority other than none to a source that holds none — neither of which is asked — EngineError::NoSuchTask when the task is not there, and EngineError::SourceFailed carrying the source’s own SourceError when it refuses or fails, so its class and its retry_after_seconds are what a caller reads. An update both setting and removing one metadata key is refused that way too, before anything is sent, in the words the source itself refuses it with. A delivered task that cannot be kept in step is not an error: it is reported failed beside the update that landed.

Source§

impl Engine

Source

pub fn build(config: &Config, secrets: &dyn SecretResolver) -> Self

Build every source a configuration names.

A source whose plugin refuses to build — a credential that is not there, a plugin whose implementation has not landed — is not fatal: it becomes an entry in every response’s errors, exactly as a source that fails mid-query does, and the other sources still answer. A user with three sources and one expired token gets the other two rather than nothing.

Source

pub fn build_with_clock( config: &Config, secrets: &dyn SecretResolver, clock: &SharedClock, ) -> Self

build, handing every in-process source clock to pace and back off on — the process’s one clock, which the binary takes from process_clock.

Source

pub fn new(sources: Vec<ConfiguredSource>, selection: Vec<SourceName>) -> Self

Drive sources built elsewhere — the engine’s own tests, and any caller holding a source it did not resolve from a configuration document.

Source

pub fn with_routes(self, routes: Routes) -> Self

The same engine, placing what is written to each source by routes.

build takes them from the configuration; a caller holding sources it built itself states them here, checked by Routes::new.

Source

pub fn place( &self, source: &SourceName, repositories: &[Repository], ) -> Placement

Where an item with repositories, written to source, lands.

Source

pub fn listing(&self) -> Vec<SourceListing>

Every configured source, whether or not it built, in name order.

Source

pub fn has(&self, name: &SourceName) -> bool

Whether this configuration has a source called name, built or not.

A caller reading a --project argument needs this: urn:project:1 is a qualified id only if urn is a source here, and a native id full of colons otherwise. That rule cannot be applied without knowing what is configured.

Source

pub async fn end_command(&self) -> Result<(), EngineError>

End one command on every source this engine holds, so the next command reads afresh.

A caller holding one engine for many units of work — a worker writing settlement after settlement back over hours — calls this between them. A source may reuse what it read within one command, so without this call a person’s edit made between two units can be overwritten by the next write. After it, no source answers a read or bases a write on item content, statuses, board contents or search results it held before. What a source keeps is its own decision, made under TaskSource::end_command’s rule; nothing here names a plugin.

The binary never calls it: one command line is one process, which drops everything at exit.

§Errors

Returns EngineError::SourceFailed for the first source that could not end its command. Every source is asked whether or not one before it failed.

Source

pub async fn tasks( &self, request: &TaskRequest, ) -> Result<QueryResponse<Qualified<Task>>, EngineError>

One page of tasks.

§Errors

Returns EngineError when the request names a source nothing configures, or carries a page token this engine did not issue. One source failing is not an error: it lands in the response’s errors.

Source

pub async fn projects( &self, request: &ProjectRequest, ) -> Result<QueryResponse<Qualified<Project>>, EngineError>

One page of projects.

§Errors

As tasks.

Source

pub async fn documents( &self, request: &DocumentRequest, ) -> Result<QueryResponse<Qualified<Document>>, EngineError>

One page of documents.

A source declaring it has no documents is not asked: the declaration is read once here, that source contributes no rows, and the plan reports Predicate::Document unavailable for it. So a document list spanning a mixed set of sources answers with what the document-bearing ones hold and says nothing alarming about the others — the same shape a source with no project table takes.

§Errors

As tasks.

Source

pub async fn labels( &self, request: &LabelRequest, ) -> Result<QueryResponse<Qualified<Label>>, EngineError>

One page of labels.

§Errors

As tasks.

Source

pub async fn search( &self, request: &SearchRequest, ) -> Result<QueryResponse<SearchHit>, EngineError>

One page of search hits, over tasks, projects, or both.

§Errors

As tasks.

Source

pub async fn task( &self, id: &GlobalId, ) -> Result<QueryResponse<Qualified<Task>>, EngineError>

One task by its qualified id, or an empty page when there is no such task.

§Errors

Returns EngineError::UnknownSource when the id names a source nothing configures.

Source

pub async fn project( &self, id: &GlobalId, ) -> Result<QueryResponse<Qualified<Project>>, EngineError>

One project by its qualified id, or an empty page when there is no such project.

§Errors

As task.

Source

pub async fn document( &self, id: &GlobalId, ) -> Result<QueryResponse<Qualified<Document>>, EngineError>

One document by its qualified id, or an empty page when there is no such document.

A source declaring it has no documents holds none, so it is not asked and the answer is the empty page with Predicate::Document reported unavailable — the same answer the list verb gives, rather than a failure.

§Errors

As task.

Source

pub async fn task_dependencies( &self, request: &DependencyRequest, ) -> Result<QueryResponse<QualifiedEdge>, EngineError>

One page of a task’s dependency edges.

§Errors

As task, plus EngineError::Token for a page token this engine did not issue.

Source

pub async fn project_dependencies( &self, request: &DependencyRequest, ) -> Result<QueryResponse<QualifiedEdge>, EngineError>

One page of a project’s dependency edges.

§Errors

As task_dependencies.

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

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