1pub mod config;
52pub mod detector;
53pub mod merger;
54
55pub use config::{BridgeConfig, JsDocConfig, ProvenanceConfig, PythonConfig, RustConfig};
56pub use detector::FormatDetector;
57pub use merger::BridgeMerger;
58
59use crate::annotate::converters::ParsedDocumentation;
60use crate::cache::{BridgeSource, ParamEntry, ReturnsEntry, SourceFormat, ThrowsEntry};
61
62#[derive(Debug, Clone, Default)]
64pub struct BridgeResult {
65 pub summary: Option<String>,
67 pub directive: Option<String>,
69 pub params: Vec<ParamEntry>,
71 pub returns: Option<ReturnsEntry>,
73 pub throws: Vec<ThrowsEntry>,
75 pub examples: Vec<String>,
77 pub source: BridgeSource,
79 pub source_formats: Vec<SourceFormat>,
81}
82
83impl BridgeResult {
84 pub fn new() -> Self {
86 Self::default()
87 }
88
89 pub fn from_acp(summary: Option<String>, directive: Option<String>) -> Self {
91 Self {
92 summary,
93 directive,
94 source: BridgeSource::Explicit,
95 source_formats: vec![SourceFormat::Acp],
96 ..Default::default()
97 }
98 }
99
100 pub fn from_native(parsed: &ParsedDocumentation, format: SourceFormat) -> Self {
102 let mut result = Self {
103 summary: parsed.summary.clone(),
104 source: BridgeSource::Converted,
105 source_formats: vec![format],
106 examples: parsed.examples.clone(),
107 ..Default::default()
108 };
109
110 for (name, type_str, desc) in &parsed.params {
112 result.params.push(ParamEntry {
113 name: name.clone(),
114 r#type: type_str.clone(),
115 type_source: type_source_from_format(format),
116 description: desc.clone(),
117 directive: None,
118 optional: false,
119 default: None,
120 source: BridgeSource::Converted,
121 source_format: Some(format),
122 source_formats: vec![],
123 });
124 }
125
126 if let Some((type_str, desc)) = &parsed.returns {
128 result.returns = Some(ReturnsEntry {
129 r#type: type_str.clone(),
130 type_source: type_source_from_format(format),
131 description: desc.clone(),
132 directive: None,
133 source: BridgeSource::Converted,
134 source_format: Some(format),
135 source_formats: vec![],
136 });
137 }
138
139 for (exc_type, desc) in &parsed.throws {
141 result.throws.push(ThrowsEntry {
142 exception: exc_type.clone(),
143 description: desc.clone(),
144 directive: None,
145 source: BridgeSource::Converted,
146 source_format: Some(format),
147 });
148 }
149
150 result
151 }
152}
153
154fn type_source_from_format(format: SourceFormat) -> Option<crate::cache::TypeSource> {
156 use crate::cache::TypeSource;
157 match format {
158 SourceFormat::Jsdoc => Some(TypeSource::Jsdoc),
159 SourceFormat::DocstringGoogle
160 | SourceFormat::DocstringNumpy
161 | SourceFormat::DocstringSphinx => Some(TypeSource::Docstring),
162 SourceFormat::Rustdoc => Some(TypeSource::Rustdoc),
163 SourceFormat::Javadoc => Some(TypeSource::Javadoc),
164 SourceFormat::TypeHint => Some(TypeSource::TypeHint),
165 _ => None,
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_bridge_result_from_acp() {
175 let result = BridgeResult::from_acp(
176 Some("Test summary".to_string()),
177 Some("MUST validate input".to_string()),
178 );
179 assert_eq!(result.summary, Some("Test summary".to_string()));
180 assert_eq!(result.directive, Some("MUST validate input".to_string()));
181 assert_eq!(result.source, BridgeSource::Explicit);
182 assert_eq!(result.source_formats, vec![SourceFormat::Acp]);
183 }
184
185 #[test]
186 fn test_bridge_result_from_native() {
187 let mut parsed = ParsedDocumentation::new();
188 parsed.summary = Some("Native summary".to_string());
189 parsed.params.push((
190 "userId".to_string(),
191 Some("string".to_string()),
192 Some("User ID".to_string()),
193 ));
194 parsed.returns = Some((
195 Some("User".to_string()),
196 Some("The user object".to_string()),
197 ));
198
199 let result = BridgeResult::from_native(&parsed, SourceFormat::Jsdoc);
200
201 assert_eq!(result.summary, Some("Native summary".to_string()));
202 assert_eq!(result.source, BridgeSource::Converted);
203 assert_eq!(result.params.len(), 1);
204 assert_eq!(result.params[0].name, "userId");
205 assert!(result.returns.is_some());
206 }
207}