Skip to main content

Templates

Struct Templates 

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

Database manager for task template operations and lifecycle management.

The Templates struct provides a comprehensive interface for managing task templates, including creation, modification, deletion, and discovery operations. It handles database connections and ensures data integrity for all template-related operations.

§Functionality Overview

  • CRUD Operations: Complete Create, Read, Update, Delete support
  • Search and Discovery: Flexible template finding and filtering
  • Validation: Ensures template uniqueness and data consistency
  • Batch Operations: Efficient handling of multiple template operations

§Database Integration

The struct automatically manages database schema initialization and provides transaction support for complex operations. It’s designed to work seamlessly with the broader kasl database ecosystem.

Implementations§

Source§

impl Templates

Source

pub fn new() -> Result<Self>

Creates a new Templates manager and initializes the database schema.

This constructor establishes a database connection, ensures the task_templates table exists with the proper schema, and prepares the manager for template operations. Schema creation is idempotent and integrates with the migration system.

§Returns

Returns a new Templates instance ready for template management, or an error if database initialization fails.

§Example
use kasl::db::templates::Templates;

let mut templates = Templates::new()?;
// Ready for template operations
§Database Integration

The templates table is officially created by migration v2, but this method ensures the table exists even in non-standard initialization scenarios. This provides robustness across different deployment patterns.

§Errors

Returns an error if:

  • Database connection cannot be established
  • Schema creation fails due to permissions or corruption
  • Migration system encounters errors during initialization
Source

pub fn create(&mut self, template: &TaskTemplate) -> Result<()>

Creates a new template in the database and validates uniqueness.

This method inserts a new template record with the provided properties, automatically assigning a unique ID and creation timestamp. Template names must be unique across the entire system.

§Validation Process
  • Uniqueness Check: Ensures template name doesn’t already exist
  • Data Validation: Validates required fields and constraints
  • Integrity Enforcement: Maintains database consistency rules
  • Automatic Fields: Sets ID and timestamp automatically
§Arguments
  • template - Template object containing the properties to store
§Returns

Returns Ok(()) if the template is created successfully, or an error if creation fails due to uniqueness violations or database issues.

§Example
use kasl::db::templates::{Templates, TaskTemplate};

let mut templates = Templates::new()?;
let template = TaskTemplate::new(
    "weekly-review".to_string(),
    "Weekly review and planning".to_string(),
    "Review accomplishments and plan next week".to_string(),
    0
);
templates.create(&template)?;
§Errors

Returns an error if:

  • A template with the same name already exists
  • Required fields are missing or invalid
  • Database constraints are violated
  • Connection or transaction failures occur
Source

pub fn update(&mut self, template: &TaskTemplate) -> Result<()>

Update an existing template

Source

pub fn delete(&mut self, name: &str) -> Result<()>

Deletes a template permanently from the database.

This method removes a template definition from the system. Note that deleting a template does not affect tasks that were previously created from that template - those tasks remain independent and unchanged.

§Impact Scope
  • Template Removal: Permanently removes the template definition
  • Task Preservation: Existing tasks created from template are unaffected
  • Reference Cleanup: Removes template from discovery and selection
  • Audit Trail: Operation can be tracked through database logs
§Arguments
  • name - Unique name identifier of the template to delete
§Returns

Returns Ok(()) if deletion succeeds, or an error if the operation fails. Deleting a non-existent template is not considered an error.

§Example
let mut templates = Templates::new()?;
templates.delete("obsolete-template")?;
§Safety Considerations
  • Deletion is immediate and permanent
  • No confirmation prompts at this level
  • Callers should implement appropriate confirmation workflows
  • Consider exporting template definitions before deletion
Source

pub fn get_all(&mut self) -> Result<Vec<TaskTemplate>>

Retrieves all templates from the database ordered alphabetically.

This method returns a complete list of all template definitions sorted by name for consistent display in user interfaces and selection menus. The list includes all template properties and metadata for comprehensive template management.

§Returns

Returns a vector of all template records ordered by name, or an error if the database query fails.

§Example
let mut templates = Templates::new()?;
let all_templates = templates.get_all()?;
for template in all_templates {
    println!("Template: {} -> {}", template.name, template.task_name);
}
§Performance Considerations

This method loads all templates into memory, which is efficient for typical template collections but may need pagination for very large numbers of templates (hundreds or thousands).

§Use Cases
  • Template selection interfaces
  • Administrative template management
  • Template export and backup operations
  • System configuration displays
Source

pub fn get(&mut self, name: &str) -> Result<Option<TaskTemplate>>

Finds a specific template by its unique name identifier.

This method performs exact name matching to retrieve a specific template definition. It’s commonly used for template editing, validation, and task creation operations that reference templates by their user-friendly names.

§Arguments
  • name - Exact name of the template to retrieve (case-sensitive)
§Returns

Returns Some(TaskTemplate) if found, None if no matching template exists, or an error if the database query fails.

§Example
let mut templates = Templates::new()?;
if let Some(template) = templates.get("daily-standup")? {
    println!("Found template: {}", template.task_name);
    // Use template to create a task with predefined values
} else {
    println!("Template 'daily-standup' not found");
}
§Name Matching
  • Performs exact, case-sensitive string matching
  • Does not support wildcards or partial matching (use search() for that)
  • Whitespace and special characters must match exactly
  • Template names are typically lowercase with hyphens for readability
Source

pub fn search(&mut self, query: &str) -> Result<Vec<TaskTemplate>>

Searches templates by name or task content with flexible pattern matching.

This method provides fuzzy search capabilities across both template names and task names, enabling users to discover relevant templates when they don’t remember exact names. It’s particularly useful for interactive template selection and discovery workflows.

§Search Behavior
  • Partial Matching: Matches substrings within template or task names
  • Case Insensitive: Search is case-insensitive for user convenience
  • Multiple Fields: Searches both template name and task_name fields
  • Sorted Results: Returns results ordered alphabetically by template name
§Search Algorithm

Uses SQL LIKE operator with wildcard patterns, which provides:

  • Substring matching anywhere in the field
  • Efficient execution using database indices
  • Consistent behavior across different database backends
§Arguments
  • query - Search term to match against template and task names
§Returns

Returns a vector of matching templates ordered by name, or an error if the database query fails. Empty vector if no matches found.

§Example
let mut templates = Templates::new()?;

// Find all templates related to "review"
let review_templates = templates.search("review")?;

// Find templates containing "standup" anywhere
let standup_templates = templates.search("standup")?;

for template in review_templates {
    println!("Found: {} -> {}", template.name, template.task_name);
}
§Performance Notes
  • LIKE queries may be slower on very large template collections
  • Consider indexing if template search becomes a performance bottleneck
  • Results are limited by available memory for the returned vector
§Use Cases
  • Interactive template selection interfaces
  • Command-line template discovery
  • Autocomplete and suggestion systems
  • Template organization and categorization
Source

pub fn exists(&mut self, name: &str) -> Result<bool>

Checks if a template with the specified name exists in the database.

This convenience method efficiently determines template existence without retrieving the full template data. It’s useful for validation before performing operations that require existing templates or for preventing duplicate template creation.

§Arguments
  • name - Unique name identifier of the template to check
§Returns

Returns true if the template exists, false otherwise, or an error if the database query fails.

§Example
let mut templates = Templates::new()?;
if templates.exists("daily-standup")? {
    println!("Template already exists");
} else {
    // Safe to create new template with this name
    let template = TaskTemplate::new(
        "daily-standup".to_string(),
        "Prepare for daily standup".to_string(),
        "Review progress and plan".to_string(),
        0
    );
    templates.create(&template)?;
}
§Performance

This method is more efficient than retrieving the full template when only existence verification is needed. It internally uses the get() method but only checks the result without processing template data.

§Use Cases
  • Template creation validation
  • User interface state management
  • Batch operation preprocessing
  • Configuration file validation

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> 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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
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 = 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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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