zarja_core/proto/
writer.rs

1//! Extensible proto writing traits.
2//!
3//! This module provides the [`ProtoWriter`] trait for customizing
4//! how proto elements are written to output.
5
6use prost_types::{
7    DescriptorProto, EnumDescriptorProto, FieldDescriptorProto, FileDescriptorProto,
8    MethodDescriptorProto, OneofDescriptorProto, ServiceDescriptorProto,
9};
10use std::fmt::Result;
11
12/// Trait for writing proto elements to output.
13///
14/// Implement this trait to customize the output format for proto definitions.
15/// The default implementation writes standard `.proto` syntax.
16///
17/// # Example
18///
19/// ```ignore
20/// use protodump_core::proto::ProtoWriter;
21///
22/// struct JsonProtoWriter {
23///     output: String,
24/// }
25///
26/// impl ProtoWriter for JsonProtoWriter {
27///     fn write_message(&mut self, message: &DescriptorProto) -> Result {
28///         // Write message as JSON
29///         self.output.push_str(&format!(r#"{{"name": "{}"}}"#, message.name()));
30///         Ok(())
31///     }
32///     // ... implement other methods
33/// }
34/// ```
35pub trait ProtoWriter {
36    /// Write the complete file descriptor
37    fn write_file(&mut self, file: &FileDescriptorProto) -> Result {
38        let _ = file;
39        Ok(())
40    }
41
42    /// Write a message definition
43    fn write_message(&mut self, message: &DescriptorProto) -> Result {
44        let _ = message;
45        Ok(())
46    }
47
48    /// Write a field definition
49    fn write_field(&mut self, field: &FieldDescriptorProto) -> Result {
50        let _ = field;
51        Ok(())
52    }
53
54    /// Write an enum definition
55    fn write_enum(&mut self, enum_type: &EnumDescriptorProto) -> Result {
56        let _ = enum_type;
57        Ok(())
58    }
59
60    /// Write a service definition
61    fn write_service(&mut self, service: &ServiceDescriptorProto) -> Result {
62        let _ = service;
63        Ok(())
64    }
65
66    /// Write a method definition
67    fn write_method(&mut self, method: &MethodDescriptorProto) -> Result {
68        let _ = method;
69        Ok(())
70    }
71
72    /// Write a oneof definition
73    fn write_oneof(&mut self, oneof: &OneofDescriptorProto) -> Result {
74        let _ = oneof;
75        Ok(())
76    }
77}
78
79/// A no-op writer that discards all output
80pub struct NullWriter;
81
82impl ProtoWriter for NullWriter {}
83
84/// A writer that collects statistics about the proto file
85#[derive(Debug, Default)]
86pub struct StatsWriter {
87    /// Number of messages
88    pub message_count: usize,
89    /// Number of fields
90    pub field_count: usize,
91    /// Number of enums
92    pub enum_count: usize,
93    /// Number of services
94    pub service_count: usize,
95    /// Number of methods
96    pub method_count: usize,
97}
98
99impl ProtoWriter for StatsWriter {
100    fn write_message(&mut self, _message: &DescriptorProto) -> Result {
101        self.message_count += 1;
102        Ok(())
103    }
104
105    fn write_field(&mut self, _field: &FieldDescriptorProto) -> Result {
106        self.field_count += 1;
107        Ok(())
108    }
109
110    fn write_enum(&mut self, _enum_type: &EnumDescriptorProto) -> Result {
111        self.enum_count += 1;
112        Ok(())
113    }
114
115    fn write_service(&mut self, _service: &ServiceDescriptorProto) -> Result {
116        self.service_count += 1;
117        Ok(())
118    }
119
120    fn write_method(&mut self, _method: &MethodDescriptorProto) -> Result {
121        self.method_count += 1;
122        Ok(())
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129
130    #[test]
131    fn test_null_writer() {
132        let mut writer = NullWriter;
133        assert!(writer.write_file(&FileDescriptorProto::default()).is_ok());
134    }
135
136    #[test]
137    fn test_stats_writer() {
138        let mut writer = StatsWriter::default();
139        writer.write_message(&DescriptorProto::default()).unwrap();
140        writer.write_message(&DescriptorProto::default()).unwrap();
141        writer.write_field(&FieldDescriptorProto::default()).unwrap();
142        
143        assert_eq!(writer.message_count, 2);
144        assert_eq!(writer.field_count, 1);
145    }
146}