bronzite_client/
reflection.rs

1//! High-level reflection API for Bronzite.
2//!
3//! This module provides an ergonomic, type-safe API for compile-time reflection.
4//! Types hold references to the client and can navigate relationships fluently.
5//!
6//! # Example
7//!
8//! ```ignore
9//! use bronzite_client::Crate;
10//!
11//! let krate = Crate::reflect("my_crate")?;
12//!
13//! // Query items with patterns
14//! let items = krate.items("bevy::prelude::*")?;
15//!
16//! // Get a specific struct and explore it
17//! let user = krate.get_struct("User")?;
18//! for field in user.fields()? {
19//!     println!("{}: {} (size: {})",
20//!         field.name,
21//!         field.ty,
22//!         field.size.unwrap_or(0)
23//!     );
24//! }
25//!
26//! // Check trait implementations
27//! if user.implements("Debug")? {
28//!     println!("User implements Debug");
29//! }
30//! ```
31
32use crate::{BronziteClient, Error, Result};
33use bronzite_types::{
34    AssocConstInfo, AssocTypeInfo, FieldInfo as RawFieldInfo, FunctionSignature, GenericParam,
35    LayoutInfo, MethodDetails as RawMethodDetails, TraitDetails as RawTraitDetails,
36    TraitImplDetails as RawTraitImpl, TypeDetails, TypeSummary, Visibility,
37};
38use std::sync::Arc;
39
40// ============================================================================
41// Core Reflection Entry Point
42// ============================================================================
43
44/// A reflected crate - the main entry point for type reflection.
45pub struct Crate {
46    name: String,
47    client: Arc<BronziteClient>,
48}
49
50impl Crate {
51    /// Reflect on a crate by name.
52    ///
53    /// This will connect to the daemon (starting it if needed) and return
54    /// a handle for querying types in the specified crate.
55    pub fn reflect(crate_name: impl Into<String>) -> Result<Self> {
56        crate::ensure_daemon_running(None)?;
57        let client = crate::connect()?;
58        Ok(Self {
59            name: crate_name.into(),
60            client: Arc::new(client),
61        })
62    }
63
64    /// Get the crate name.
65    pub fn name(&self) -> &str {
66        &self.name
67    }
68
69    /// Get all items matching a pattern.
70    ///
71    /// Supports:
72    /// - Exact: `"foo::Bar"`
73    /// - Wildcard: `"foo::Bar*"`
74    /// - Single-level glob: `"foo::*"` (matches `foo::Bar` but not `foo::bar::Baz`)
75    /// - Recursive glob: `"foo::**"` (matches all descendants)
76    pub fn items(&self, pattern: &str) -> Result<Vec<Item>> {
77        let types = self.client_mut()?.find_types(&self.name, pattern)?;
78
79        types
80            .into_iter()
81            .map(|summary| Item::from_summary(summary, &self.name, Arc::clone(&self.client)))
82            .collect()
83    }
84
85    /// Get all structs matching a pattern.
86    pub fn structs(&self, pattern: &str) -> Result<Vec<StructDef>> {
87        let items = self.items(pattern)?;
88        Ok(items
89            .into_iter()
90            .filter_map(|item| match item {
91                Item::Struct(s) => Some(s),
92                _ => None,
93            })
94            .collect())
95    }
96
97    /// Get all enums matching a pattern.
98    pub fn enums(&self, pattern: &str) -> Result<Vec<EnumDef>> {
99        let items = self.items(pattern)?;
100        Ok(items
101            .into_iter()
102            .filter_map(|item| match item {
103                Item::Enum(e) => Some(e),
104                _ => None,
105            })
106            .collect())
107    }
108
109    /// Get all traits matching a pattern.
110    pub fn traits(&self, pattern: &str) -> Result<Vec<TraitDef>> {
111        let all_traits = self.client_mut()?.get_traits(&self.name)?;
112
113        let matching: Vec<_> = all_traits
114            .into_iter()
115            .filter(|t| bronzite_types::path_matches_pattern(&t.path, pattern))
116            .collect();
117
118        matching
119            .into_iter()
120            .map(|info| TraitDef::from_info(info, &self.name, Arc::clone(&self.client)))
121            .collect()
122    }
123
124    /// Get a specific struct by path.
125    pub fn get_struct(&self, path: &str) -> Result<StructDef> {
126        let details = self.client_mut()?.get_type(&self.name, path)?;
127        StructDef::from_details(details, &self.name, Arc::clone(&self.client))
128    }
129
130    /// Get a specific enum by path.
131    pub fn get_enum(&self, path: &str) -> Result<EnumDef> {
132        let details = self.client_mut()?.get_type(&self.name, path)?;
133        EnumDef::from_details(details, &self.name, Arc::clone(&self.client))
134    }
135
136    /// Get a specific trait by path.
137    pub fn get_trait(&self, path: &str) -> Result<TraitDef> {
138        let details = self.client_mut()?.get_trait(&self.name, path)?;
139        TraitDef::from_trait_details(details, &self.name, Arc::clone(&self.client))
140    }
141
142    /// Get a specific type alias by path.
143    pub fn get_type_alias(&self, path: &str) -> Result<TypeAliasDef> {
144        let (original, resolved, chain) = self.client_mut()?.resolve_alias(&self.name, path)?;
145        Ok(TypeAliasDef {
146            path: original,
147            resolved_path: resolved,
148            resolution_chain: chain,
149            crate_name: self.name.clone(),
150            client: Arc::clone(&self.client),
151        })
152    }
153
154    /// Helper to get mutable client access (Arc doesn't need Mutex for single-threaded use).
155    fn client_mut(&self) -> Result<&mut BronziteClient> {
156        // SAFETY: This is safe in proc-macro context where we're single-threaded.
157        // Arc is used for cheap cloning, not thread-safety here.
158        unsafe {
159            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
160            Ok(&mut *ptr)
161        }
162    }
163}
164
165// ============================================================================
166// Item Enum - Unified Type Representation
167// ============================================================================
168
169/// A unified representation of any Rust item (struct, enum, trait, etc).
170///
171/// This enum provides a type-safe way to work with different kinds of items
172/// discovered through pattern matching or queries. Each variant contains
173/// a specific type definition with navigation methods.
174///
175/// # Example
176///
177/// ```ignore
178/// use bronzite_client::{Crate, Item};
179///
180/// let krate = Crate::reflect("my_crate")?;
181/// for item in krate.items("*")? {
182///     match item {
183///         Item::Struct(s) => println!("Struct: {}", s.name),
184///         Item::Enum(e) => println!("Enum: {}", e.name),
185///         Item::Trait(t) => println!("Trait: {}", t.name),
186///         Item::TypeAlias(a) => println!("Alias: {}", a.path),
187///         Item::Union(u) => println!("Union: {}", u.name),
188///     }
189/// }
190/// ```
191#[derive(Debug, Clone)]
192pub enum Item {
193    /// A struct definition
194    Struct(StructDef),
195    /// An enum definition
196    Enum(EnumDef),
197    /// A trait definition
198    Trait(TraitDef),
199    /// A type alias
200    TypeAlias(TypeAliasDef),
201    /// A union definition
202    Union(UnionDef),
203}
204
205impl Item {
206    /// Get the name of this item.
207    pub fn name(&self) -> &str {
208        match self {
209            Item::Struct(s) => &s.name,
210            Item::Enum(e) => &e.name,
211            Item::Trait(t) => &t.name,
212            Item::TypeAlias(a) => &a.path,
213            Item::Union(u) => &u.name,
214        }
215    }
216
217    /// Get the full path of this item.
218    pub fn path(&self) -> &str {
219        match self {
220            Item::Struct(s) => &s.path,
221            Item::Enum(e) => &e.path,
222            Item::Trait(t) => &t.path,
223            Item::TypeAlias(a) => &a.path,
224            Item::Union(u) => &u.path,
225        }
226    }
227
228    fn from_summary(
229        summary: TypeSummary,
230        crate_name: &str,
231        client: Arc<BronziteClient>,
232    ) -> Result<Self> {
233        match summary.kind {
234            bronzite_types::TypeKind::Struct => Ok(Item::Struct(StructDef {
235                name: summary.name,
236                path: summary.path,
237                generics: summary.generics,
238                crate_name: crate_name.to_string(),
239                client,
240                cached_details: None,
241            })),
242            bronzite_types::TypeKind::Enum => Ok(Item::Enum(EnumDef {
243                name: summary.name,
244                path: summary.path,
245                generics: summary.generics,
246                crate_name: crate_name.to_string(),
247                client,
248                cached_details: None,
249            })),
250            bronzite_types::TypeKind::Union => Ok(Item::Union(UnionDef {
251                name: summary.name,
252                path: summary.path,
253                generics: summary.generics,
254                crate_name: crate_name.to_string(),
255                client,
256            })),
257            bronzite_types::TypeKind::Trait => {
258                // For traits, we need to fetch full details
259                let client_mut = unsafe {
260                    let ptr = Arc::as_ptr(&client) as *mut BronziteClient;
261                    &mut *ptr
262                };
263                let details = client_mut.get_trait(crate_name, &summary.path)?;
264                Ok(Item::Trait(TraitDef::from_trait_details(
265                    details, crate_name, client,
266                )?))
267            }
268            _ => Err(Error::UnexpectedResponse),
269        }
270    }
271}
272
273// ============================================================================
274// Struct Definition
275// ============================================================================
276
277/// A reflected struct definition with navigation methods.
278///
279/// Provides access to struct metadata and navigation to related types like
280/// fields, trait implementations, and methods.
281///
282/// # Example
283///
284/// ```ignore
285/// use bronzite_client::Crate;
286///
287/// let krate = Crate::reflect("my_crate")?;
288/// let user = krate.get_struct("User")?;
289///
290/// // Get fields
291/// for field in user.fields()? {
292///     println!("Field: {} of type {}",
293///         field.name.unwrap_or_default(),
294///         field.ty
295///     );
296/// }
297///
298/// // Check trait implementation
299/// if user.implements("Debug")? {
300///     println!("User implements Debug");
301/// }
302///
303/// // Get methods
304/// for method in user.methods()? {
305///     println!("Method: {}", method.name);
306/// }
307/// ```
308#[derive(Debug, Clone)]
309pub struct StructDef {
310    /// The struct's name (without path)
311    pub name: String,
312    /// The struct's full path
313    pub path: String,
314    /// Generic parameters
315    pub generics: Vec<GenericParam>,
316    crate_name: String,
317    client: Arc<BronziteClient>,
318    cached_details: Option<Box<TypeDetails>>,
319}
320
321impl StructDef {
322    fn from_details(
323        details: TypeDetails,
324        crate_name: &str,
325        client: Arc<BronziteClient>,
326    ) -> Result<Self> {
327        Ok(Self {
328            name: details.name.clone(),
329            path: details.path.clone(),
330            generics: details.generics.clone(),
331            crate_name: crate_name.to_string(),
332            client,
333            cached_details: Some(Box::new(details)),
334        })
335    }
336
337    /// Get the struct's fields.
338    pub fn fields(&self) -> Result<Vec<Field>> {
339        let fields = self
340            .client_mut()?
341            .get_fields(&self.crate_name, &self.path)?;
342        Ok(fields
343            .into_iter()
344            .map(|f| Field::from_raw(f, &self.crate_name, Arc::clone(&self.client)))
345            .collect())
346    }
347
348    /// Get trait implementations for this struct.
349    pub fn trait_impls(&self) -> Result<Vec<TraitImpl>> {
350        let impls = self
351            .client_mut()?
352            .get_trait_impls(&self.crate_name, &self.path)?;
353        Ok(impls
354            .into_iter()
355            .map(|i| TraitImpl::from_raw(i, &self.crate_name, Arc::clone(&self.client)))
356            .collect())
357    }
358
359    /// Check if this struct implements a specific trait.
360    pub fn implements(&self, trait_path: &str) -> Result<bool> {
361        let (implements, _) =
362            self.client_mut()?
363                .check_impl(&self.crate_name, &self.path, trait_path)?;
364        Ok(implements)
365    }
366
367    /// Get inherent methods (from `impl StructName { ... }` blocks).
368    pub fn methods(&self) -> Result<Vec<Method>> {
369        let impls = self
370            .client_mut()?
371            .get_inherent_impls(&self.crate_name, &self.path)?;
372        Ok(impls
373            .into_iter()
374            .flat_map(|impl_block| {
375                impl_block
376                    .methods
377                    .into_iter()
378                    .map(|m| Method::from_raw(m, &self.crate_name, Arc::clone(&self.client)))
379            })
380            .collect())
381    }
382
383    /// Get memory layout information.
384    pub fn layout(&self) -> Result<LayoutInfo> {
385        self.client_mut()?.get_layout(&self.crate_name, &self.path)
386    }
387
388    /// Get the source code of this struct definition.
389    pub fn source(&self) -> Option<&str> {
390        self.details().and_then(|d| d.source.as_deref())
391    }
392
393    /// Get detailed type information.
394    pub fn details(&self) -> Option<&TypeDetails> {
395        self.cached_details.as_deref()
396    }
397
398    /// Get visibility of this struct.
399    pub fn visibility(&self) -> Option<&Visibility> {
400        self.details().map(|d| &d.visibility)
401    }
402
403    /// Get doc comments.
404    pub fn docs(&self) -> Option<&str> {
405        self.details().and_then(|d| d.docs.as_deref())
406    }
407
408    fn client_mut(&self) -> Result<&mut BronziteClient> {
409        unsafe {
410            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
411            Ok(&mut *ptr)
412        }
413    }
414}
415
416// ============================================================================
417// Enum Definition
418// ============================================================================
419
420/// A reflected enum definition.
421#[derive(Debug, Clone)]
422pub struct EnumDef {
423    pub name: String,
424    pub path: String,
425    pub generics: Vec<GenericParam>,
426    crate_name: String,
427    client: Arc<BronziteClient>,
428    cached_details: Option<Box<TypeDetails>>,
429}
430
431impl EnumDef {
432    fn from_details(
433        details: TypeDetails,
434        crate_name: &str,
435        client: Arc<BronziteClient>,
436    ) -> Result<Self> {
437        Ok(Self {
438            name: details.name.clone(),
439            path: details.path.clone(),
440            generics: details.generics.clone(),
441            crate_name: crate_name.to_string(),
442            client,
443            cached_details: Some(Box::new(details)),
444        })
445    }
446
447    /// Get the enum's variants.
448    pub fn variants(&self) -> Option<&[bronzite_types::EnumVariantInfo]> {
449        self.details().and_then(|d| d.variants.as_deref())
450    }
451
452    /// Get trait implementations for this enum.
453    pub fn trait_impls(&self) -> Result<Vec<TraitImpl>> {
454        let impls = self
455            .client_mut()?
456            .get_trait_impls(&self.crate_name, &self.path)?;
457        Ok(impls
458            .into_iter()
459            .map(|i| TraitImpl::from_raw(i, &self.crate_name, Arc::clone(&self.client)))
460            .collect())
461    }
462
463    /// Check if this enum implements a specific trait.
464    pub fn implements(&self, trait_path: &str) -> Result<bool> {
465        let (implements, _) =
466            self.client_mut()?
467                .check_impl(&self.crate_name, &self.path, trait_path)?;
468        Ok(implements)
469    }
470
471    /// Get inherent methods.
472    pub fn methods(&self) -> Result<Vec<Method>> {
473        let impls = self
474            .client_mut()?
475            .get_inherent_impls(&self.crate_name, &self.path)?;
476        Ok(impls
477            .into_iter()
478            .flat_map(|impl_block| {
479                impl_block
480                    .methods
481                    .into_iter()
482                    .map(|m| Method::from_raw(m, &self.crate_name, Arc::clone(&self.client)))
483            })
484            .collect())
485    }
486
487    /// Get the source code of this enum definition.
488    pub fn source(&self) -> Option<&str> {
489        self.details().and_then(|d| d.source.as_deref())
490    }
491
492    pub fn details(&self) -> Option<&TypeDetails> {
493        self.cached_details.as_deref()
494    }
495
496    pub fn visibility(&self) -> Option<&Visibility> {
497        self.details().map(|d| &d.visibility)
498    }
499
500    pub fn docs(&self) -> Option<&str> {
501        self.details().and_then(|d| d.docs.as_deref())
502    }
503
504    fn client_mut(&self) -> Result<&mut BronziteClient> {
505        unsafe {
506            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
507            Ok(&mut *ptr)
508        }
509    }
510}
511
512// ============================================================================
513// Union Definition
514// ============================================================================
515
516/// A reflected union definition.
517#[derive(Debug, Clone)]
518pub struct UnionDef {
519    pub name: String,
520    pub path: String,
521    pub generics: Vec<GenericParam>,
522    crate_name: String,
523    client: Arc<BronziteClient>,
524}
525
526impl UnionDef {
527    /// Get the union's fields.
528    pub fn fields(&self) -> Result<Vec<Field>> {
529        let fields = self
530            .client_mut()?
531            .get_fields(&self.crate_name, &self.path)?;
532        Ok(fields
533            .into_iter()
534            .map(|f| Field::from_raw(f, &self.crate_name, Arc::clone(&self.client)))
535            .collect())
536    }
537
538    fn client_mut(&self) -> Result<&mut BronziteClient> {
539        unsafe {
540            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
541            Ok(&mut *ptr)
542        }
543    }
544}
545
546// ============================================================================
547// Trait Definition
548// ============================================================================
549
550/// A reflected trait definition.
551#[derive(Debug, Clone)]
552pub struct TraitDef {
553    pub name: String,
554    pub path: String,
555    pub generics: Vec<GenericParam>,
556    pub is_auto: bool,
557    pub is_unsafe: bool,
558    pub supertraits: Vec<String>,
559    pub source: Option<String>,
560    pub docs: Option<String>,
561    crate_name: String,
562    client: Arc<BronziteClient>,
563    cached_details: Option<Box<RawTraitDetails>>,
564}
565
566impl TraitDef {
567    fn from_info(
568        info: bronzite_types::TraitInfo,
569        crate_name: &str,
570        client: Arc<BronziteClient>,
571    ) -> Result<Self> {
572        // Fetch full details
573        let client_mut = unsafe {
574            let ptr = Arc::as_ptr(&client) as *mut BronziteClient;
575            &mut *ptr
576        };
577        let details = client_mut.get_trait(crate_name, &info.path)?;
578        Self::from_trait_details(details, crate_name, client)
579    }
580
581    fn from_trait_details(
582        details: RawTraitDetails,
583        crate_name: &str,
584        client: Arc<BronziteClient>,
585    ) -> Result<Self> {
586        Ok(Self {
587            name: details.name.clone(),
588            path: details.path.clone(),
589            generics: details.generics.clone(),
590            is_auto: details.is_auto,
591            is_unsafe: details.is_unsafe,
592            supertraits: details.supertraits.clone(),
593            source: details.source.clone(),
594            docs: details.docs.clone(),
595            crate_name: crate_name.to_string(),
596            client,
597            cached_details: Some(Box::new(details)),
598        })
599    }
600
601    /// Get all methods defined in this trait.
602    pub fn methods(&self) -> Vec<TraitMethod> {
603        self.cached_details
604            .as_ref()
605            .map(|d| {
606                d.methods
607                    .iter()
608                    .map(|m| TraitMethod {
609                        name: m.name.clone(),
610                        signature: m.signature.clone(),
611                        parsed_signature: m.parsed_signature.clone(),
612                        has_default: m.has_default,
613                        default_body: m.default_body.clone(),
614                        is_unsafe: m.is_unsafe,
615                        docs: m.docs.clone(),
616                    })
617                    .collect()
618            })
619            .unwrap_or_default()
620    }
621
622    /// Get associated types.
623    pub fn associated_types(&self) -> Vec<&AssocTypeInfo> {
624        self.cached_details
625            .as_ref()
626            .map(|d| d.assoc_types.iter().collect())
627            .unwrap_or_default()
628    }
629
630    /// Get associated constants.
631    pub fn associated_consts(&self) -> Vec<&AssocConstInfo> {
632        self.cached_details
633            .as_ref()
634            .map(|d| d.assoc_consts.iter().collect())
635            .unwrap_or_default()
636    }
637
638    /// Get all types that implement this trait.
639    pub fn implementors(&self) -> Result<Vec<Item>> {
640        let types = self
641            .client_mut()?
642            .get_implementors(&self.crate_name, &self.path)?;
643        types
644            .into_iter()
645            .map(|summary| Item::from_summary(summary, &self.crate_name, Arc::clone(&self.client)))
646            .collect()
647    }
648
649    fn client_mut(&self) -> Result<&mut BronziteClient> {
650        unsafe {
651            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
652            Ok(&mut *ptr)
653        }
654    }
655}
656
657/// A method defined in a trait.
658#[derive(Debug, Clone)]
659pub struct TraitMethod {
660    pub name: String,
661    pub signature: String,
662    pub parsed_signature: FunctionSignature,
663    pub has_default: bool,
664    pub default_body: Option<String>,
665    pub is_unsafe: bool,
666    pub docs: Option<String>,
667}
668
669// ============================================================================
670// Type Alias Definition
671// ============================================================================
672
673/// A reflected type alias.
674#[derive(Debug, Clone)]
675pub struct TypeAliasDef {
676    pub path: String,
677    pub resolved_path: String,
678    pub resolution_chain: Vec<String>,
679    crate_name: String,
680    client: Arc<BronziteClient>,
681}
682
683impl TypeAliasDef {
684    /// Resolve this alias to its concrete type.
685    pub fn resolve(&self) -> Result<Item> {
686        // Get the final resolved type
687        let details = self
688            .client_mut()?
689            .get_type(&self.crate_name, &self.resolved_path)?;
690
691        let summary = TypeSummary {
692            name: details.name.clone(),
693            path: details.path.clone(),
694            kind: details.kind.clone(),
695            generics: details.generics.clone(),
696        };
697
698        Item::from_summary(summary, &self.crate_name, Arc::clone(&self.client))
699    }
700
701    fn client_mut(&self) -> Result<&mut BronziteClient> {
702        unsafe {
703            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
704            Ok(&mut *ptr)
705        }
706    }
707}
708
709// ============================================================================
710// Field
711// ============================================================================
712
713/// A field of a struct, enum variant, or union.
714///
715/// Provides field metadata and the ability to navigate to the field's type definition.
716///
717/// # Example
718///
719/// ```ignore
720/// let user = krate.get_struct("User")?;
721/// for field in user.fields()? {
722///     println!("Field: {}", field.name.as_deref().unwrap_or("<unnamed>"));
723///     println!("  Type: {}", field.ty);
724///     println!("  Size: {:?}", field.size);
725///
726///     // Navigate to the field's type definition
727///     if let Some(field_type) = field.type_def()? {
728///         println!("  Defined in: {}", field_type.path());
729///     }
730/// }
731/// ```
732#[derive(Debug, Clone)]
733pub struct Field {
734    /// Field name (None for tuple struct fields)
735    pub name: Option<String>,
736    /// Field index in the struct
737    pub index: usize,
738    /// Type as a string
739    pub ty: String,
740    /// Resolved type (following aliases)
741    pub resolved_ty: Option<String>,
742    /// Field visibility
743    pub visibility: Visibility,
744    /// Doc comments
745    pub docs: Option<String>,
746    /// Offset in bytes (if layout is known)
747    pub offset: Option<usize>,
748    /// Size in bytes (if layout is known)
749    pub size: Option<usize>,
750    crate_name: String,
751    client: Arc<BronziteClient>,
752}
753
754impl Field {
755    fn from_raw(raw: RawFieldInfo, crate_name: &str, client: Arc<BronziteClient>) -> Self {
756        Self {
757            name: raw.name,
758            index: raw.index,
759            ty: raw.ty,
760            resolved_ty: raw.resolved_ty,
761            visibility: raw.visibility,
762            docs: raw.docs,
763            offset: raw.offset,
764            size: raw.size,
765            crate_name: crate_name.to_string(),
766            client,
767        }
768    }
769
770    /// Get the type definition for this field's type.
771    pub fn type_def(&self) -> Result<Option<Item>> {
772        let type_path = self.resolved_ty.as_ref().unwrap_or(&self.ty);
773
774        // Try to get type details
775        match self.client_mut()?.get_type(&self.crate_name, type_path) {
776            Ok(details) => {
777                let summary = TypeSummary {
778                    name: details.name.clone(),
779                    path: details.path.clone(),
780                    kind: details.kind.clone(),
781                    generics: details.generics.clone(),
782                };
783                Ok(Some(Item::from_summary(
784                    summary,
785                    &self.crate_name,
786                    Arc::clone(&self.client),
787                )?))
788            }
789            Err(_) => Ok(None), // Type might be external or primitive
790        }
791    }
792
793    fn client_mut(&self) -> Result<&mut BronziteClient> {
794        unsafe {
795            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
796            Ok(&mut *ptr)
797        }
798    }
799}
800
801// ============================================================================
802// Trait Implementation
803// ============================================================================
804
805/// A trait implementation block.
806#[derive(Debug, Clone)]
807pub struct TraitImpl {
808    pub trait_path: String,
809    pub generics: Vec<GenericParam>,
810    pub is_unsafe: bool,
811    pub source: Option<String>,
812    raw: RawTraitImpl,
813    crate_name: String,
814    client: Arc<BronziteClient>,
815}
816
817impl TraitImpl {
818    fn from_raw(raw: RawTraitImpl, crate_name: &str, client: Arc<BronziteClient>) -> Self {
819        Self {
820            trait_path: raw.trait_path.clone(),
821            generics: raw.generics.clone(),
822            is_unsafe: raw.is_unsafe,
823            source: raw.source.clone(),
824            raw,
825            crate_name: crate_name.to_string(),
826            client,
827        }
828    }
829
830    /// Get the trait definition being implemented.
831    pub fn trait_def(&self) -> Result<TraitDef> {
832        let details = self
833            .client_mut()?
834            .get_trait(&self.crate_name, &self.trait_path)?;
835        TraitDef::from_trait_details(details, &self.crate_name, Arc::clone(&self.client))
836    }
837
838    /// Get methods defined in this impl block.
839    pub fn methods(&self) -> Vec<Method> {
840        self.raw
841            .methods
842            .iter()
843            .map(|m| Method::from_raw(m.clone(), &self.crate_name, Arc::clone(&self.client)))
844            .collect()
845    }
846
847    /// Get associated types in this impl.
848    pub fn associated_types(&self) -> &[AssocTypeInfo] {
849        &self.raw.assoc_types
850    }
851
852    /// Get associated constants in this impl.
853    pub fn associated_consts(&self) -> &[AssocConstInfo] {
854        &self.raw.assoc_consts
855    }
856
857    fn client_mut(&self) -> Result<&mut BronziteClient> {
858        unsafe {
859            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
860            Ok(&mut *ptr)
861        }
862    }
863}
864
865// ============================================================================
866// Method
867// ============================================================================
868
869/// A method (from an impl block).
870///
871/// Provides method metadata including signature, source code, and the ability
872/// to navigate to parameter and return types.
873///
874/// # Example
875///
876/// ```ignore
877/// let user = krate.get_struct("User")?;
878/// for method in user.methods()? {
879///     println!("Method: {}", method.name);
880///     println!("  Signature: {}", method.signature);
881///
882///     // Get return type
883///     if let Some(return_type) = method.return_type_def()? {
884///         println!("  Returns: {}", return_type.name());
885///     }
886///
887///     // Get method body source
888///     if let Some(body) = &method.body_source {
889///         println!("  Body: {}", body);
890///     }
891/// }
892/// ```
893#[derive(Debug, Clone)]
894pub struct Method {
895    /// Method name
896    pub name: String,
897    /// Full signature as a string
898    pub signature: String,
899    /// Parsed signature components
900    pub parsed_signature: FunctionSignature,
901    /// Method body source code (if available)
902    pub body_source: Option<String>,
903    /// Whether this is an unsafe method
904    pub is_unsafe: bool,
905    /// Whether this is a const method
906    pub is_const: bool,
907    /// Whether this is an async method
908    pub is_async: bool,
909    /// Doc comments
910    pub docs: Option<String>,
911    crate_name: String,
912    client: Arc<BronziteClient>,
913}
914
915impl Method {
916    fn from_raw(raw: RawMethodDetails, crate_name: &str, client: Arc<BronziteClient>) -> Self {
917        Self {
918            name: raw.name,
919            signature: raw.signature,
920            parsed_signature: raw.parsed_signature,
921            body_source: raw.body_source,
922            is_unsafe: raw.is_unsafe,
923            is_const: raw.is_const,
924            is_async: raw.is_async,
925            docs: raw.docs,
926            crate_name: crate_name.to_string(),
927            client,
928        }
929    }
930
931    /// Get the return type as an Item if it's a known type.
932    pub fn return_type_def(&self) -> Result<Option<Item>> {
933        if let Some(return_ty) = &self.parsed_signature.return_ty {
934            match self.client_mut()?.get_type(&self.crate_name, return_ty) {
935                Ok(details) => {
936                    let summary = TypeSummary {
937                        name: details.name.clone(),
938                        path: details.path.clone(),
939                        kind: details.kind.clone(),
940                        generics: details.generics.clone(),
941                    };
942                    Ok(Some(Item::from_summary(
943                        summary,
944                        &self.crate_name,
945                        Arc::clone(&self.client),
946                    )?))
947                }
948                Err(_) => Ok(None),
949            }
950        } else {
951            Ok(None)
952        }
953    }
954
955    /// Get parameter type definitions.
956    pub fn param_types(&self) -> Result<Vec<Option<Item>>> {
957        self.parsed_signature
958            .params
959            .iter()
960            .map(
961                |param| match self.client_mut()?.get_type(&self.crate_name, &param.ty) {
962                    Ok(details) => {
963                        let summary = TypeSummary {
964                            name: details.name.clone(),
965                            path: details.path.clone(),
966                            kind: details.kind.clone(),
967                            generics: details.generics.clone(),
968                        };
969                        Ok(Some(Item::from_summary(
970                            summary,
971                            &self.crate_name,
972                            Arc::clone(&self.client),
973                        )?))
974                    }
975                    Err(_) => Ok(None),
976                },
977            )
978            .collect()
979    }
980
981    fn client_mut(&self) -> Result<&mut BronziteClient> {
982        unsafe {
983            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
984            Ok(&mut *ptr)
985        }
986    }
987}