Skip to main content

yapi_types/
config.rs

1//! pi's JSON configuration files and how pi lays each one out on disk.
2
3use serde::Serialize;
4
5use crate::json;
6
7/// A JSON configuration file in the agent or project directory.
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum ConfigFile {
10    /// `settings.json`, global and project scope.
11    Settings,
12    /// `auth.json`, global scope.
13    Auth,
14    /// `models.json`, global scope. pi reads it but never writes it.
15    Models,
16    /// `keybindings.json`, global scope.
17    Keybindings,
18    /// `mcp.json`, global and project scope.
19    Mcp,
20    /// `mcp-auth.json`, global scope: OAuth state of MCP servers.
21    McpAuth,
22}
23
24impl ConfigFile {
25    /// File name inside the agent or project directory.
26    pub fn file_name(self) -> &'static str {
27        match self {
28            Self::Settings => "settings.json",
29            Self::Auth => "auth.json",
30            Self::Models => "models.json",
31            Self::Keybindings => "keybindings.json",
32            Self::Mcp => "mcp.json",
33            Self::McpAuth => "mcp-auth.json",
34        }
35    }
36
37    /// Whether pi ends the file with a newline.
38    pub fn trailing_newline(self) -> bool {
39        matches!(self, Self::Keybindings | Self::Mcp | Self::McpAuth)
40    }
41
42    /// Serializes `document` as pi writes this file: two-space indent, then the
43    /// trailing newline policy. pi re-detects the indent of an existing `mcp.json`;
44    /// two spaces is its default.
45    pub fn render<T: Serialize + ?Sized>(self, document: &T) -> serde_json::Result<String> {
46        let mut text = json::to_string_pretty(document, "  ")?;
47        if self.trailing_newline() {
48            text.push('\n');
49        }
50        Ok(text)
51    }
52}