pyo3_stub_gen/docgen/
default_parser.rs1use crate::docgen::ir::{DocDefaultExpression, DocDefaultValue, DocTypeRef};
4use crate::docgen::link::LinkResolver;
5use crate::docgen::util::prefix_stripper;
6use crate::TypeInfo;
7
8pub struct DefaultValueParser<'a> {
10 link_resolver: &'a LinkResolver<'a>,
11 current_module: &'a str,
12}
13
14impl<'a> DefaultValueParser<'a> {
15 pub fn new(link_resolver: &'a LinkResolver<'a>, current_module: &'a str) -> Self {
16 Self {
17 link_resolver,
18 current_module,
19 }
20 }
21
22 pub fn parse(&self, default_str: &str, type_info: &TypeInfo) -> DocDefaultValue {
24 let display = self.strip_module_prefixes(default_str);
26
27 if let Some(type_ref) = self.try_parse_attribute_ref(&display, type_info) {
29 return DocDefaultValue::Expression(DocDefaultExpression {
30 display: display.clone(),
31 type_refs: vec![type_ref],
32 });
33 }
34
35 DocDefaultValue::Simple {
37 value: display.clone(),
38 }
39 }
40
41 fn strip_module_prefixes(&self, text: &str) -> String {
43 prefix_stripper::strip_default_value_prefixes(text)
44 }
45
46 fn try_parse_attribute_ref(&self, text: &str, _type_info: &TypeInfo) -> Option<DocTypeRef> {
48 let parts: Vec<&str> = text.split('.').collect();
50 if parts.len() != 2 {
51 return None;
52 }
53
54 let class_name = parts[0];
55 let attribute_name = parts[1];
56
57 let class_suffix = format!(".{}", class_name);
60 let class_fqn = self
61 .link_resolver
62 .export_map()
63 .keys()
64 .find(|fqn| fqn.ends_with(&class_suffix) || *fqn == class_name)?;
65
66 let link_target = self.link_resolver.resolve_attribute_link(
68 class_fqn,
69 attribute_name,
70 self.current_module,
71 )?;
72
73 Some(DocTypeRef {
74 text: text.to_string(),
75 offset: 0,
76 link_target: Some(link_target),
77 })
78 }
79}