1use super::CodeGenerator;
2use crate::lexicon::{
3 LexArrayItem, LexObjectProperty, LexString, LexStringFormat, LexUserType,
4};
5
6impl<'c> CodeGenerator<'c> {
7 /// Check if a property type needs a lifetime parameter
8 pub(super) fn property_needs_lifetime(&self, prop: &LexObjectProperty<'static>) -> bool {
9 match prop {
10 LexObjectProperty::Boolean(_) | LexObjectProperty::Integer(_) => false,
11 LexObjectProperty::String(s) => self.string_needs_lifetime(s),
12 LexObjectProperty::Bytes(_) => false, // Bytes is owned
13 LexObjectProperty::CidLink(_)
14 | LexObjectProperty::Blob(_)
15 | LexObjectProperty::Unknown(_) => true,
16 LexObjectProperty::Array(array) => self.array_item_needs_lifetime(&array.items),
17 LexObjectProperty::Object(_) => true, // Nested objects have lifetimes
18 LexObjectProperty::Ref(ref_type) => {
19 // Check if the ref target actually needs a lifetime
20 self.ref_needs_lifetime(&ref_type.r#ref)
21 }
22 LexObjectProperty::Union(_) => true, // Unions generally have lifetimes
23 }
24 }
25
26 /// Check if an array item type needs a lifetime parameter
27 pub(super) fn array_item_needs_lifetime(&self, item: &LexArrayItem) -> bool {
28 match item {
29 LexArrayItem::Boolean(_) | LexArrayItem::Integer(_) => false,
30 LexArrayItem::String(s) => self.string_needs_lifetime(s),
31 LexArrayItem::Bytes(_) => false,
32 LexArrayItem::CidLink(_) | LexArrayItem::Blob(_) | LexArrayItem::Unknown(_) => true,
33 LexArrayItem::Object(_) => true, // Nested objects have lifetimes
34 LexArrayItem::Ref(ref_type) => self.ref_needs_lifetime(&ref_type.r#ref),
35 LexArrayItem::Union(_) => true,
36 }
37 }
38
39 /// Check if a string type needs a lifetime parameter
40 pub(super) fn string_needs_lifetime(&self, s: &LexString) -> bool {
41 match s.format {
42 Some(LexStringFormat::Datetime)
43 | Some(LexStringFormat::Language)
44 | Some(LexStringFormat::Tid) => false,
45 _ => true, // Most string types borrow
46 }
47 }
48
49 /// Check if a ref needs a lifetime parameter
50 pub(super) fn ref_needs_lifetime(&self, ref_str: &str) -> bool {
51 // Try to resolve the ref
52 if let Some((_doc, def)) = self.corpus.resolve_ref(ref_str) {
53 self.def_needs_lifetime(def)
54 } else {
55 // If we can't resolve it, assume it needs a lifetime (safe default)
56 true
57 }
58 }
59
60 /// Check if a lexicon def needs a lifetime parameter
61 pub(super) fn def_needs_lifetime(&self, def: &LexUserType<'static>) -> bool {
62 match def {
63 // Records and Objects always have lifetimes now since they get #[lexicon] attribute
64 LexUserType::Record(_) => true,
65 LexUserType::Object(_) => true,
66 LexUserType::Token(_) => false,
67 LexUserType::String(s) => {
68 // Check if it's a known values enum or a regular string
69 if s.known_values.is_some() {
70 // Known values enums have Other(CowStr<'a>) variant
71 true
72 } else {
73 self.string_needs_lifetime(s)
74 }
75 }
76 LexUserType::Integer(_) => false,
77 LexUserType::Boolean(_) => false,
78 LexUserType::Bytes(_) => false,
79 LexUserType::CidLink(_) | LexUserType::Blob(_) | LexUserType::Unknown(_) => true,
80 LexUserType::Array(array) => self.array_item_needs_lifetime(&array.items),
81 LexUserType::XrpcQuery(_)
82 | LexUserType::XrpcProcedure(_)
83 | LexUserType::XrpcSubscription(_) => {
84 // XRPC types generate multiple structs, not a single type we can reference
85 // Shouldn't be referenced directly
86 true
87 }
88 }
89 }
90
91 /// Check if xrpc params need a lifetime parameter
92 pub(super) fn params_need_lifetime(&self, params: &crate::lexicon::LexXrpcParameters<'static>) -> bool {
93 params.properties.values().any(|prop| {
94 use crate::lexicon::LexXrpcParametersProperty;
95 match prop {
96 LexXrpcParametersProperty::Boolean(_) | LexXrpcParametersProperty::Integer(_) => {
97 false
98 }
99 LexXrpcParametersProperty::String(s) => self.string_needs_lifetime(s),
100 LexXrpcParametersProperty::Unknown(_) => true,
101 LexXrpcParametersProperty::Array(arr) => {
102 use crate::lexicon::LexPrimitiveArrayItem;
103 match &arr.items {
104 LexPrimitiveArrayItem::Boolean(_) | LexPrimitiveArrayItem::Integer(_) => {
105 false
106 }
107 LexPrimitiveArrayItem::String(s) => self.string_needs_lifetime(s),
108 LexPrimitiveArrayItem::Unknown(_) => true,
109 }
110 }
111 }
112 })
113 }
114}