secrets_core/
spec_registry.rs1use crate::SecretSpec;
2use serde_json::json;
3use std::collections::BTreeMap;
4
5#[derive(Default)]
7pub struct SecretSpecRegistry {
8 by_name: BTreeMap<&'static str, SecretSpec>,
9}
10
11impl SecretSpecRegistry {
12 pub fn new() -> Self {
14 Self::default()
15 }
16
17 pub fn extend_with(&mut self, specs: &'static [SecretSpec]) {
19 for spec in specs {
20 match self.by_name.get(spec.name) {
21 None => {
22 self.by_name.insert(spec.name, spec.clone());
23 }
24 Some(existing) => {
25 let better = match (existing.description, spec.description) {
26 (None, Some(_)) => true,
27 (Some(a), Some(b)) if b.len() > a.len() => true,
28 _ => false,
29 };
30 if better {
31 self.by_name.insert(spec.name, spec.clone());
32 }
33 }
34 }
35 }
36 }
37
38 pub fn all(&self) -> impl Iterator<Item = &SecretSpec> {
40 self.by_name.values()
41 }
42
43 pub fn to_markdown_table(&self) -> String {
45 let mut out = String::from("| Name | Description |\n|---|---|\n");
46 for spec in self.by_name.values() {
47 let desc = spec.description.unwrap_or("");
48 out.push_str(&format!(
49 "| `{name}` | {desc} |\n",
50 name = spec.name,
51 desc = desc
52 ));
53 }
54 out
55 }
56
57 pub fn to_json(&self) -> serde_json::Value {
59 let entries = self
60 .by_name
61 .values()
62 .map(|spec| {
63 json!({
64 "name": spec.name,
65 "description": spec.description,
66 })
67 })
68 .collect();
69 serde_json::Value::Array(entries)
70 }
71}