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 all fields of this struct.
338    ///
339    /// Returns a vector of [`Field`] objects, each representing a field in the struct.
340    /// Fields include metadata like name, type, visibility, size, and offset.
341    ///
342    /// # Example
343    ///
344    /// ```ignore
345    /// let user = krate.get_struct("User")?;
346    /// for field in user.fields()? {
347    ///     println!("Field: {} of type {}",
348    ///         field.name.as_deref().unwrap_or("<unnamed>"),
349    ///         field.ty
350    ///     );
351    ///     if let Some(size) = field.size {
352    ///         println!("  Size: {} bytes", size);
353    ///     }
354    /// }
355    /// ```
356    pub fn fields(&self) -> Result<Vec<Field>> {
357        let fields = self
358            .client_mut()?
359            .get_fields(&self.crate_name, &self.path)?;
360        Ok(fields
361            .into_iter()
362            .map(|f| Field::from_raw(f, &self.crate_name, Arc::clone(&self.client)))
363            .collect())
364    }
365
366    /// Get all trait implementations for this struct.
367    ///
368    /// Returns a vector of [`TraitImpl`] objects containing information about each
369    /// trait implementation, including methods, associated types, and source code.
370    ///
371    /// # Example
372    ///
373    /// ```ignore
374    /// let user = krate.get_struct("User")?;
375    /// for impl_block in user.trait_impls()? {
376    ///     println!("Implements: {}", impl_block.trait_path);
377    ///     for method in impl_block.methods() {
378    ///         println!("  - {}", method.name);
379    ///     }
380    /// }
381    /// ```
382    pub fn trait_impls(&self) -> Result<Vec<TraitImpl>> {
383        let impls = self
384            .client_mut()?
385            .get_trait_impls(&self.crate_name, &self.path)?;
386        Ok(impls
387            .into_iter()
388            .map(|i| TraitImpl::from_raw(i, &self.crate_name, Arc::clone(&self.client)))
389            .collect())
390    }
391
392    /// Check if this struct implements a specific trait.
393    ///
394    /// This is a convenient way to test for trait implementation without
395    /// fetching all trait impls.
396    ///
397    /// # Arguments
398    ///
399    /// * `trait_path` - The trait path to check (e.g., "Debug", "std::fmt::Display")
400    ///
401    /// # Example
402    ///
403    /// ```ignore
404    /// let user = krate.get_struct("User")?;
405    /// if user.implements("Debug")? {
406    ///     println!("User can be debug-printed");
407    /// }
408    /// if user.implements("std::clone::Clone")? {
409    ///     println!("User can be cloned");
410    /// }
411    /// ```
412    pub fn implements(&self, trait_path: &str) -> Result<bool> {
413        let (implements, _) =
414            self.client_mut()?
415                .check_impl(&self.crate_name, &self.path, trait_path)?;
416        Ok(implements)
417    }
418
419    /// Get inherent methods (from `impl StructName { ... }` blocks).
420    ///
421    /// Returns methods defined in inherent impl blocks, not trait implementations.
422    /// Each [`Method`] includes the signature, body source, and navigation to
423    /// parameter/return types.
424    ///
425    /// # Example
426    ///
427    /// ```ignore
428    /// let user = krate.get_struct("User")?;
429    /// for method in user.methods()? {
430    ///     println!("Method: {}", method.signature);
431    ///     if let Some(body) = &method.body_source {
432    ///         println!("  Implementation: {}", body);
433    ///     }
434    ///     if let Some(ret_type) = method.return_type_def()? {
435    ///         println!("  Returns: {}", ret_type.name());
436    ///     }
437    /// }
438    /// ```
439    pub fn methods(&self) -> Result<Vec<Method>> {
440        let impls = self
441            .client_mut()?
442            .get_inherent_impls(&self.crate_name, &self.path)?;
443        Ok(impls
444            .into_iter()
445            .flat_map(|impl_block| {
446                impl_block
447                    .methods
448                    .into_iter()
449                    .map(|m| Method::from_raw(m, &self.crate_name, Arc::clone(&self.client)))
450            })
451            .collect())
452    }
453
454    /// Get memory layout information for this struct.
455    ///
456    /// Returns [`LayoutInfo`] containing size, alignment, field offsets,
457    /// and auto-trait implementations (Send, Sync, Copy).
458    ///
459    /// # Example
460    ///
461    /// ```ignore
462    /// let user = krate.get_struct("User")?;
463    /// let layout = user.layout()?;
464    /// println!("Size: {} bytes", layout.size);
465    /// println!("Alignment: {} bytes", layout.align);
466    /// println!("Is Copy: {}", layout.is_copy);
467    /// ```
468    pub fn layout(&self) -> Result<LayoutInfo> {
469        self.client_mut()?.get_layout(&self.crate_name, &self.path)
470    }
471
472    /// Get the source code of this struct definition.
473    pub fn source(&self) -> Option<&str> {
474        self.details().and_then(|d| d.source.as_deref())
475    }
476
477    /// Get detailed type information.
478    pub fn details(&self) -> Option<&TypeDetails> {
479        self.cached_details.as_deref()
480    }
481
482    /// Get visibility of this struct.
483    pub fn visibility(&self) -> Option<&Visibility> {
484        self.details().map(|d| &d.visibility)
485    }
486
487    /// Get doc comments.
488    pub fn docs(&self) -> Option<&str> {
489        self.details().and_then(|d| d.docs.as_deref())
490    }
491
492    fn client_mut(&self) -> Result<&mut BronziteClient> {
493        unsafe {
494            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
495            Ok(&mut *ptr)
496        }
497    }
498}
499
500// ============================================================================
501// Enum Definition
502// ============================================================================
503
504/// A reflected enum definition.
505#[derive(Debug, Clone)]
506pub struct EnumDef {
507    pub name: String,
508    pub path: String,
509    pub generics: Vec<GenericParam>,
510    crate_name: String,
511    client: Arc<BronziteClient>,
512    cached_details: Option<Box<TypeDetails>>,
513}
514
515impl EnumDef {
516    fn from_details(
517        details: TypeDetails,
518        crate_name: &str,
519        client: Arc<BronziteClient>,
520    ) -> Result<Self> {
521        Ok(Self {
522            name: details.name.clone(),
523            path: details.path.clone(),
524            generics: details.generics.clone(),
525            crate_name: crate_name.to_string(),
526            client,
527            cached_details: Some(Box::new(details)),
528        })
529    }
530
531    /// Get the enum's variants.
532    pub fn variants(&self) -> Option<&[bronzite_types::EnumVariantInfo]> {
533        self.details().and_then(|d| d.variants.as_deref())
534    }
535
536    /// Get trait implementations for this enum.
537    pub fn trait_impls(&self) -> Result<Vec<TraitImpl>> {
538        let impls = self
539            .client_mut()?
540            .get_trait_impls(&self.crate_name, &self.path)?;
541        Ok(impls
542            .into_iter()
543            .map(|i| TraitImpl::from_raw(i, &self.crate_name, Arc::clone(&self.client)))
544            .collect())
545    }
546
547    /// Check if this enum implements a specific trait.
548    pub fn implements(&self, trait_path: &str) -> Result<bool> {
549        let (implements, _) =
550            self.client_mut()?
551                .check_impl(&self.crate_name, &self.path, trait_path)?;
552        Ok(implements)
553    }
554
555    /// Get inherent methods.
556    pub fn methods(&self) -> Result<Vec<Method>> {
557        let impls = self
558            .client_mut()?
559            .get_inherent_impls(&self.crate_name, &self.path)?;
560        Ok(impls
561            .into_iter()
562            .flat_map(|impl_block| {
563                impl_block
564                    .methods
565                    .into_iter()
566                    .map(|m| Method::from_raw(m, &self.crate_name, Arc::clone(&self.client)))
567            })
568            .collect())
569    }
570
571    /// Get the source code of this enum definition.
572    pub fn source(&self) -> Option<&str> {
573        self.details().and_then(|d| d.source.as_deref())
574    }
575
576    pub fn details(&self) -> Option<&TypeDetails> {
577        self.cached_details.as_deref()
578    }
579
580    pub fn visibility(&self) -> Option<&Visibility> {
581        self.details().map(|d| &d.visibility)
582    }
583
584    pub fn docs(&self) -> Option<&str> {
585        self.details().and_then(|d| d.docs.as_deref())
586    }
587
588    fn client_mut(&self) -> Result<&mut BronziteClient> {
589        unsafe {
590            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
591            Ok(&mut *ptr)
592        }
593    }
594}
595
596// ============================================================================
597// Union Definition
598// ============================================================================
599
600/// A reflected union definition.
601#[derive(Debug, Clone)]
602pub struct UnionDef {
603    pub name: String,
604    pub path: String,
605    pub generics: Vec<GenericParam>,
606    crate_name: String,
607    client: Arc<BronziteClient>,
608}
609
610impl UnionDef {
611    /// Get the union's fields.
612    pub fn fields(&self) -> Result<Vec<Field>> {
613        let fields = self
614            .client_mut()?
615            .get_fields(&self.crate_name, &self.path)?;
616        Ok(fields
617            .into_iter()
618            .map(|f| Field::from_raw(f, &self.crate_name, Arc::clone(&self.client)))
619            .collect())
620    }
621
622    fn client_mut(&self) -> Result<&mut BronziteClient> {
623        unsafe {
624            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
625            Ok(&mut *ptr)
626        }
627    }
628}
629
630// ============================================================================
631// Trait Definition
632// ============================================================================
633
634/// A reflected trait definition.
635#[derive(Debug, Clone)]
636pub struct TraitDef {
637    pub name: String,
638    pub path: String,
639    pub generics: Vec<GenericParam>,
640    pub is_auto: bool,
641    pub is_unsafe: bool,
642    pub supertraits: Vec<String>,
643    pub source: Option<String>,
644    pub docs: Option<String>,
645    crate_name: String,
646    client: Arc<BronziteClient>,
647    cached_details: Option<Box<RawTraitDetails>>,
648}
649
650impl TraitDef {
651    fn from_info(
652        info: bronzite_types::TraitInfo,
653        crate_name: &str,
654        client: Arc<BronziteClient>,
655    ) -> Result<Self> {
656        // Fetch full details
657        let client_mut = unsafe {
658            let ptr = Arc::as_ptr(&client) as *mut BronziteClient;
659            &mut *ptr
660        };
661        let details = client_mut.get_trait(crate_name, &info.path)?;
662        Self::from_trait_details(details, crate_name, client)
663    }
664
665    fn from_trait_details(
666        details: RawTraitDetails,
667        crate_name: &str,
668        client: Arc<BronziteClient>,
669    ) -> Result<Self> {
670        Ok(Self {
671            name: details.name.clone(),
672            path: details.path.clone(),
673            generics: details.generics.clone(),
674            is_auto: details.is_auto,
675            is_unsafe: details.is_unsafe,
676            supertraits: details.supertraits.clone(),
677            source: details.source.clone(),
678            docs: details.docs.clone(),
679            crate_name: crate_name.to_string(),
680            client,
681            cached_details: Some(Box::new(details)),
682        })
683    }
684
685    /// Get all methods defined in this trait.
686    pub fn methods(&self) -> Vec<TraitMethod> {
687        self.cached_details
688            .as_ref()
689            .map(|d| {
690                d.methods
691                    .iter()
692                    .map(|m| TraitMethod {
693                        name: m.name.clone(),
694                        signature: m.signature.clone(),
695                        parsed_signature: m.parsed_signature.clone(),
696                        has_default: m.has_default,
697                        default_body: m.default_body.clone(),
698                        is_unsafe: m.is_unsafe,
699                        docs: m.docs.clone(),
700                    })
701                    .collect()
702            })
703            .unwrap_or_default()
704    }
705
706    /// Get associated types.
707    pub fn associated_types(&self) -> Vec<&AssocTypeInfo> {
708        self.cached_details
709            .as_ref()
710            .map(|d| d.assoc_types.iter().collect())
711            .unwrap_or_default()
712    }
713
714    /// Get associated constants.
715    pub fn associated_consts(&self) -> Vec<&AssocConstInfo> {
716        self.cached_details
717            .as_ref()
718            .map(|d| d.assoc_consts.iter().collect())
719            .unwrap_or_default()
720    }
721
722    /// Get all types that implement this trait.
723    pub fn implementors(&self) -> Result<Vec<Item>> {
724        let types = self
725            .client_mut()?
726            .get_implementors(&self.crate_name, &self.path)?;
727        types
728            .into_iter()
729            .map(|summary| Item::from_summary(summary, &self.crate_name, Arc::clone(&self.client)))
730            .collect()
731    }
732
733    fn client_mut(&self) -> Result<&mut BronziteClient> {
734        unsafe {
735            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
736            Ok(&mut *ptr)
737        }
738    }
739}
740
741/// A method defined in a trait.
742#[derive(Debug, Clone)]
743pub struct TraitMethod {
744    pub name: String,
745    pub signature: String,
746    pub parsed_signature: FunctionSignature,
747    pub has_default: bool,
748    pub default_body: Option<String>,
749    pub is_unsafe: bool,
750    pub docs: Option<String>,
751}
752
753// ============================================================================
754// Type Alias Definition
755// ============================================================================
756
757/// A reflected type alias.
758#[derive(Debug, Clone)]
759pub struct TypeAliasDef {
760    pub path: String,
761    pub resolved_path: String,
762    pub resolution_chain: Vec<String>,
763    crate_name: String,
764    client: Arc<BronziteClient>,
765}
766
767impl TypeAliasDef {
768    /// Resolve this alias to its concrete type.
769    pub fn resolve(&self) -> Result<Item> {
770        // Get the final resolved type
771        let details = self
772            .client_mut()?
773            .get_type(&self.crate_name, &self.resolved_path)?;
774
775        let summary = TypeSummary {
776            name: details.name.clone(),
777            path: details.path.clone(),
778            kind: details.kind.clone(),
779            generics: details.generics.clone(),
780        };
781
782        Item::from_summary(summary, &self.crate_name, Arc::clone(&self.client))
783    }
784
785    fn client_mut(&self) -> Result<&mut BronziteClient> {
786        unsafe {
787            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
788            Ok(&mut *ptr)
789        }
790    }
791}
792
793// ============================================================================
794// Field
795// ============================================================================
796
797/// A field of a struct, enum variant, or union.
798///
799/// Provides field metadata and the ability to navigate to the field's type definition.
800///
801/// # Example
802///
803/// ```ignore
804/// let user = krate.get_struct("User")?;
805/// for field in user.fields()? {
806///     println!("Field: {}", field.name.as_deref().unwrap_or("<unnamed>"));
807///     println!("  Type: {}", field.ty);
808///     println!("  Size: {:?}", field.size);
809///
810///     // Navigate to the field's type definition
811///     if let Some(field_type) = field.type_def()? {
812///         println!("  Defined in: {}", field_type.path());
813///     }
814/// }
815/// ```
816#[derive(Debug, Clone)]
817pub struct Field {
818    /// Field name (None for tuple struct fields)
819    pub name: Option<String>,
820    /// Field index in the struct
821    pub index: usize,
822    /// Type as a string
823    pub ty: String,
824    /// Resolved type (following aliases)
825    pub resolved_ty: Option<String>,
826    /// Field visibility
827    pub visibility: Visibility,
828    /// Doc comments
829    pub docs: Option<String>,
830    /// Offset in bytes (if layout is known)
831    pub offset: Option<usize>,
832    /// Size in bytes (if layout is known)
833    pub size: Option<usize>,
834    crate_name: String,
835    client: Arc<BronziteClient>,
836}
837
838impl Field {
839    fn from_raw(raw: RawFieldInfo, crate_name: &str, client: Arc<BronziteClient>) -> Self {
840        Self {
841            name: raw.name,
842            index: raw.index,
843            ty: raw.ty,
844            resolved_ty: raw.resolved_ty,
845            visibility: raw.visibility,
846            docs: raw.docs,
847            offset: raw.offset,
848            size: raw.size,
849            crate_name: crate_name.to_string(),
850            client,
851        }
852    }
853
854    /// Navigate to the type definition for this field's type.
855    ///
856    /// Returns an [`Item`] representing the field's type definition, if it
857    /// can be resolved. Returns `None` for primitive types or external types
858    /// not in the queried crate.
859    ///
860    /// # Example
861    ///
862    /// ```ignore
863    /// let user = krate.get_struct("User")?;
864    /// for field in user.fields()? {
865    ///     if let Some(field_type) = field.type_def()? {
866    ///         match field_type {
867    ///             Item::Struct(s) => println!("{} is a struct", field.name.unwrap()),
868    ///             Item::Enum(e) => println!("{} is an enum", field.name.unwrap()),
869    ///             _ => {}
870    ///         }
871    ///     }
872    /// }
873    /// ```
874    ///
875    /// # Returns
876    ///
877    /// - `Ok(Some(Item))` - The type definition was found
878    /// - `Ok(None)` - The type is primitive or external
879    /// - `Err(_)` - An error occurred querying the daemon
880    pub fn type_def(&self) -> Result<Option<Item>> {
881        let type_path = self.resolved_ty.as_ref().unwrap_or(&self.ty);
882
883        // Try to get type details
884        match self.client_mut()?.get_type(&self.crate_name, type_path) {
885            Ok(details) => {
886                let summary = TypeSummary {
887                    name: details.name.clone(),
888                    path: details.path.clone(),
889                    kind: details.kind.clone(),
890                    generics: details.generics.clone(),
891                };
892                Ok(Some(Item::from_summary(
893                    summary,
894                    &self.crate_name,
895                    Arc::clone(&self.client),
896                )?))
897            }
898            Err(_) => Ok(None), // Type might be external or primitive
899        }
900    }
901
902    fn client_mut(&self) -> Result<&mut BronziteClient> {
903        unsafe {
904            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
905            Ok(&mut *ptr)
906        }
907    }
908}
909
910// ============================================================================
911// Trait Implementation
912// ============================================================================
913
914/// A trait implementation block.
915#[derive(Debug, Clone)]
916pub struct TraitImpl {
917    pub trait_path: String,
918    pub generics: Vec<GenericParam>,
919    pub is_unsafe: bool,
920    pub source: Option<String>,
921    raw: RawTraitImpl,
922    crate_name: String,
923    client: Arc<BronziteClient>,
924}
925
926impl TraitImpl {
927    fn from_raw(raw: RawTraitImpl, crate_name: &str, client: Arc<BronziteClient>) -> Self {
928        Self {
929            trait_path: raw.trait_path.clone(),
930            generics: raw.generics.clone(),
931            is_unsafe: raw.is_unsafe,
932            source: raw.source.clone(),
933            raw,
934            crate_name: crate_name.to_string(),
935            client,
936        }
937    }
938
939    /// Navigate to the trait definition being implemented.
940    ///
941    /// Returns the [`TraitDef`] for the trait that this impl block implements.
942    ///
943    /// # Example
944    ///
945    /// ```ignore
946    /// let user = krate.get_struct("User")?;
947    /// for impl_block in user.trait_impls()? {
948    ///     let trait_def = impl_block.trait_def()?;
949    ///     println!("Implements trait: {}", trait_def.name);
950    ///     println!("Trait has {} methods", trait_def.methods().len());
951    /// }
952    /// ```
953    pub fn trait_def(&self) -> Result<TraitDef> {
954        let details = self
955            .client_mut()?
956            .get_trait(&self.crate_name, &self.trait_path)?;
957        TraitDef::from_trait_details(details, &self.crate_name, Arc::clone(&self.client))
958    }
959
960    /// Get methods defined in this impl block.
961    pub fn methods(&self) -> Vec<Method> {
962        self.raw
963            .methods
964            .iter()
965            .map(|m| Method::from_raw(m.clone(), &self.crate_name, Arc::clone(&self.client)))
966            .collect()
967    }
968
969    /// Get associated types in this impl.
970    pub fn associated_types(&self) -> &[AssocTypeInfo] {
971        &self.raw.assoc_types
972    }
973
974    /// Get associated constants in this impl.
975    pub fn associated_consts(&self) -> &[AssocConstInfo] {
976        &self.raw.assoc_consts
977    }
978
979    fn client_mut(&self) -> Result<&mut BronziteClient> {
980        unsafe {
981            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
982            Ok(&mut *ptr)
983        }
984    }
985}
986
987// ============================================================================
988// Method
989// ============================================================================
990
991/// A method (from an impl block).
992///
993/// Provides method metadata including signature, source code, and the ability
994/// to navigate to parameter and return types.
995///
996/// # Example
997///
998/// ```ignore
999/// let user = krate.get_struct("User")?;
1000/// for method in user.methods()? {
1001///     println!("Method: {}", method.name);
1002///     println!("  Signature: {}", method.signature);
1003///
1004///     // Get return type
1005///     if let Some(return_type) = method.return_type_def()? {
1006///         println!("  Returns: {}", return_type.name());
1007///     }
1008///
1009///     // Get method body source
1010///     if let Some(body) = &method.body_source {
1011///         println!("  Body: {}", body);
1012///     }
1013/// }
1014/// ```
1015#[derive(Debug, Clone)]
1016pub struct Method {
1017    /// Method name
1018    pub name: String,
1019    /// Full signature as a string
1020    pub signature: String,
1021    /// Parsed signature components
1022    pub parsed_signature: FunctionSignature,
1023    /// Method body source code (if available)
1024    pub body_source: Option<String>,
1025    /// Whether this is an unsafe method
1026    pub is_unsafe: bool,
1027    /// Whether this is a const method
1028    pub is_const: bool,
1029    /// Whether this is an async method
1030    pub is_async: bool,
1031    /// Doc comments
1032    pub docs: Option<String>,
1033    crate_name: String,
1034    client: Arc<BronziteClient>,
1035}
1036
1037impl Method {
1038    fn from_raw(raw: RawMethodDetails, crate_name: &str, client: Arc<BronziteClient>) -> Self {
1039        Self {
1040            name: raw.name,
1041            signature: raw.signature,
1042            parsed_signature: raw.parsed_signature,
1043            body_source: raw.body_source,
1044            is_unsafe: raw.is_unsafe,
1045            is_const: raw.is_const,
1046            is_async: raw.is_async,
1047            docs: raw.docs,
1048            crate_name: crate_name.to_string(),
1049            client,
1050        }
1051    }
1052
1053    /// Navigate to the return type definition.
1054    ///
1055    /// Returns an [`Item`] representing the method's return type definition,
1056    /// if it can be resolved. Returns `None` if the method returns `()`, or
1057    /// if the type is primitive or external.
1058    ///
1059    /// # Example
1060    ///
1061    /// ```ignore
1062    /// let user = krate.get_struct("User")?;
1063    /// for method in user.methods()? {
1064    ///     if let Some(return_type) = method.return_type_def()? {
1065    ///         println!("{} returns {}", method.name, return_type.name());
1066    ///     }
1067    /// }
1068    /// ```
1069    ///
1070    /// # Returns
1071    ///
1072    /// - `Ok(Some(Item))` - The return type definition was found
1073    /// - `Ok(None)` - No return type, or primitive/external type
1074    /// - `Err(_)` - An error occurred querying the daemon
1075    pub fn return_type_def(&self) -> Result<Option<Item>> {
1076        if let Some(return_ty) = &self.parsed_signature.return_ty {
1077            match self.client_mut()?.get_type(&self.crate_name, return_ty) {
1078                Ok(details) => {
1079                    let summary = TypeSummary {
1080                        name: details.name.clone(),
1081                        path: details.path.clone(),
1082                        kind: details.kind.clone(),
1083                        generics: details.generics.clone(),
1084                    };
1085                    Ok(Some(Item::from_summary(
1086                        summary,
1087                        &self.crate_name,
1088                        Arc::clone(&self.client),
1089                    )?))
1090                }
1091                Err(_) => Ok(None),
1092            }
1093        } else {
1094            Ok(None)
1095        }
1096    }
1097
1098    /// Navigate to parameter type definitions.
1099    ///
1100    /// Returns a vector of optional [`Item`]s, one for each parameter.
1101    /// Each entry is `Some(Item)` if the type can be resolved, or `None`
1102    /// for primitive/external types.
1103    ///
1104    /// # Example
1105    ///
1106    /// ```ignore
1107    /// let user = krate.get_struct("User")?;
1108    /// for method in user.methods()? {
1109    ///     println!("Method: {}", method.name);
1110    ///     for (i, param_type) in method.param_types()?.into_iter().enumerate() {
1111    ///         if let Some(ptype) = param_type {
1112    ///             println!("  Param {}: {}", i, ptype.name());
1113    ///         }
1114    ///     }
1115    /// }
1116    /// ```
1117    ///
1118    /// # Returns
1119    ///
1120    /// A vector where each element corresponds to a parameter:
1121    /// - `Some(Item)` - The parameter type was found
1122    /// - `None` - The type is primitive or external
1123    pub fn param_types(&self) -> Result<Vec<Option<Item>>> {
1124        self.parsed_signature
1125            .params
1126            .iter()
1127            .map(
1128                |param| match self.client_mut()?.get_type(&self.crate_name, &param.ty) {
1129                    Ok(details) => {
1130                        let summary = TypeSummary {
1131                            name: details.name.clone(),
1132                            path: details.path.clone(),
1133                            kind: details.kind.clone(),
1134                            generics: details.generics.clone(),
1135                        };
1136                        Ok(Some(Item::from_summary(
1137                            summary,
1138                            &self.crate_name,
1139                            Arc::clone(&self.client),
1140                        )?))
1141                    }
1142                    Err(_) => Ok(None),
1143                },
1144            )
1145            .collect()
1146    }
1147
1148    fn client_mut(&self) -> Result<&mut BronziteClient> {
1149        unsafe {
1150            let ptr = Arc::as_ptr(&self.client) as *mut BronziteClient;
1151            Ok(&mut *ptr)
1152        }
1153    }
1154}