use crate::root_envelopes::{RootEnvelopeMode, serialize_named_json_output};
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ListOutput<Boundaries, Diagnostic> {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub plugins: Option<Vec<ListPluginOutput>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub file_count: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub files: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub entry_point_count: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub entry_points: Option<Vec<ListEntryPointOutput>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub boundaries: Option<Boundaries>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub workspace_count: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub workspaces: Option<Vec<WorkspaceInfo>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub workspace_diagnostics: Option<Vec<Diagnostic>>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ListPluginOutput {
pub name: String,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ListEntryPointOutput {
pub path: String,
pub source: String,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[cfg_attr(
feature = "schema",
schemars(title = "fallow list --boundaries --format json")
)]
pub struct ListBoundariesOutput<Status, Rule> {
pub boundaries: BoundariesListing<Status, Rule>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[cfg_attr(
feature = "schema",
schemars(title = "fallow workspaces --format json")
)]
pub struct WorkspacesOutput<Diagnostic> {
pub workspace_count: usize,
pub workspaces: Vec<WorkspaceInfo>,
pub workspace_diagnostics: Vec<Diagnostic>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct WorkspaceInfo {
pub name: String,
pub path: String,
pub is_internal_dependency: bool,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct BoundariesListing<Status, Rule> {
pub configured: bool,
pub zone_count: usize,
pub zones: Vec<BoundariesListZone>,
pub rule_count: usize,
pub rules: Vec<BoundariesListRule>,
pub logical_group_count: usize,
pub logical_groups: Vec<BoundariesListLogicalGroup<Status, Rule>>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct BoundariesListZone {
pub name: String,
pub patterns: Vec<String>,
pub file_count: usize,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct BoundariesListRule {
pub from: String,
pub allow: Vec<String>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct BoundariesListLogicalGroup<Status, Rule> {
pub name: String,
pub children: Vec<String>,
pub auto_discover: Vec<String>,
pub status: Status,
pub source_zone_index: usize,
pub file_count: usize,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authored_rule: Option<Rule>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub fallback_zone: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub merged_from: Option<Vec<usize>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub original_zone_root: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub child_source_indices: Vec<usize>,
}
pub fn serialize_list_boundaries_json_output<T: Serialize>(
output: T,
mode: RootEnvelopeMode,
) -> Result<serde_json::Value, serde_json::Error> {
serialize_named_json_output(output, "list-boundaries", mode)
}
pub fn serialize_list_workspaces_json_output<T: Serialize>(
output: T,
mode: RootEnvelopeMode,
) -> Result<serde_json::Value, serde_json::Error> {
serialize_named_json_output(output, "list-workspaces", mode)
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn list_boundaries_json_output_uses_output_owned_root_contract() {
let value = serialize_list_boundaries_json_output(
json!({"boundaries": {}}),
RootEnvelopeMode::Tagged,
)
.expect("list boundaries output should serialize");
assert_eq!(value["kind"], "list-boundaries");
}
#[test]
fn list_workspaces_json_output_uses_output_owned_root_contract() {
let value = serialize_list_workspaces_json_output(
json!({"workspace_count": 0, "workspaces": []}),
RootEnvelopeMode::Tagged,
)
.expect("list workspaces output should serialize");
assert_eq!(value["kind"], "list-workspaces");
}
}