Skip to main content

systemprompt_models/services/
rules.rs

1//! Rule configuration and disk-descriptor model.
2//!
3//! A *rule* is a markdown instruction fragment an organisation ships to its
4//! agents through a plugin bundle. [`DiskRuleConfig`] is the per-rule on-disk
5//! descriptor at `rules/<id>/config.yaml`, naming the markdown file that
6//! carries the rule text. Unlike the skill and hook descriptors this one is
7//! also serialisable: the marketplace importer writes these files from an
8//! Anthropic `rules/*.md` tree, so read and write share one shape.
9//!
10//! Copyright (c) systemprompt.io — Business Source License 1.1.
11//! See <https://systemprompt.io> for licensing details.
12
13use serde::{Deserialize, Serialize};
14
15use crate::bridge::ids::RuleId;
16
17const fn default_true() -> bool {
18    true
19}
20
21pub const RULE_CONFIG_FILENAME: &str = "config.yaml";
22
23pub const DEFAULT_RULE_CONTENT_FILE: &str = "index.md";
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct DiskRuleConfig {
27    pub id: RuleId,
28    pub name: String,
29    pub description: String,
30    #[serde(default = "default_true")]
31    pub enabled: bool,
32    #[serde(default, skip_serializing_if = "String::is_empty")]
33    pub file: String,
34    #[serde(default, skip_serializing_if = "Vec::is_empty")]
35    pub tags: Vec<String>,
36    #[serde(default, skip_serializing_if = "Vec::is_empty")]
37    pub hosts: Vec<String>,
38}
39
40impl DiskRuleConfig {
41    #[must_use]
42    pub fn content_file(&self) -> &str {
43        if self.file.is_empty() {
44            DEFAULT_RULE_CONTENT_FILE
45        } else {
46            &self.file
47        }
48    }
49}