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}