A better Rust ATProto crate
1//! Compile-time validation crate for Pretty and Macro codegen modes.
2//!
3//! This crate has no runtime functionality. Its purpose is to verify that
4//! code generated in both Pretty mode (short names + use blocks) and Macro mode
5//! (fully-qualified paths) compiles successfully. The build script generates
6//! code from curated test lexicons into `src/generated/{pretty,macro_mode}/`.
7//!
8//! If this crate compiles, both codegen modes produce valid Rust.
9
10extern crate alloc;
11
12// Both generated module trees emit `use crate::builder_types::{...}` in
13// their state modules. This is hardcoded in the codegen, so re-export from
14// one of the generated copies at the crate root.
15#[path = "generated/pretty/builder_types.rs"]
16pub mod builder_types;
17
18// Pretty mode generated code — module tree with proper path resolution.
19// The build script generates with root_module="crate::pretty" so that
20// cross-module refs like `crate::pretty::app_bsky::...` resolve correctly
21// through the #[path] module boundary.
22#[path = "generated/pretty/lib.rs"]
23pub mod pretty;
24
25// Macro mode generated code (root_module="crate::macro_mode").
26#[path = "generated/macro_mode/lib.rs"]
27pub mod macro_mode;
28
29// Serde spike: empirical validation for borrow-or-share type param + serde interaction.
30mod serde_spike;
31
32#[cfg(test)]
33mod tests {
34 // -- Pretty mode type accessibility --
35
36 #[test]
37 fn pretty_strong_ref_accessible() {
38 // Compile-time type check: strongRef from com.atproto.repo.
39 let _: Option<super::pretty::com_atproto::repo::strong_ref::StrongRef> = None;
40 }
41
42 #[test]
43 fn pretty_facet_types_accessible() {
44 // Compile-time type check: facet and its sub-defs.
45 let _: Option<super::pretty::app_bsky::richtext::facet::Facet> = None;
46 let _: Option<super::pretty::app_bsky::richtext::facet::Mention> = None;
47 let _: Option<super::pretty::app_bsky::richtext::facet::Link> = None;
48 let _: Option<super::pretty::app_bsky::richtext::facet::Tag> = None;
49 let _: Option<super::pretty::app_bsky::richtext::facet::ByteSlice> = None;
50 }
51
52 #[test]
53 fn pretty_label_defs_accessible() {
54 // Compile-time type check: defs types from com.atproto.label.
55 let _: Option<super::pretty::com_atproto::label::Label> = None;
56 }
57
58 #[test]
59 fn pretty_embed_external_accessible() {
60 // Compile-time type check: embed external types.
61 let _: Option<super::pretty::app_bsky::embed::external::ExternalRecord> = None;
62 let _: Option<super::pretty::app_bsky::embed::external::External> = None;
63 let _: Option<super::pretty::app_bsky::embed::external::View> = None;
64 let _: Option<super::pretty::app_bsky::embed::external::ViewExternal> = None;
65 }
66
67 #[test]
68 fn pretty_collision_collection_accessible() {
69 // Compile-time type check: local Collection type compiles despite trait name collision.
70 // The record is named CollectionRecord, the local def is Collection.
71 let _: Option<super::pretty::test_collision::collection::CollectionRecord> = None;
72 let _: Option<super::pretty::test_collision::collection::Collection> = None;
73 }
74
75 #[test]
76 fn pretty_collision_did_accessible() {
77 // Compile-time type check: local Did type compiles despite string type name collision.
78 // The main def is DidRecord, the local def is Did.
79 let _: Option<super::pretty::test_collision::did::DidRecord> = None;
80 let _: Option<super::pretty::test_collision::did::Did> = None;
81 }
82
83 #[test]
84 fn pretty_collision_option_accessible() {
85 // Compile-time type check: local Option type compiles despite std Option collision.
86 // The main def is OptionRecord, the local def is OptionRecordOption.
87 let _: Option<super::pretty::test_collision::option::OptionRecord> = None;
88 let _: Option<super::pretty::test_collision::option::OptionRecordOption> = None;
89 }
90
91 #[test]
92 fn pretty_cross_namespace_ns1_accessible() {
93 // Compile-time type check: types defined in test.ns1.defs.
94 let _: Option<super::pretty::test_ns1::Foo> = None;
95 let _: Option<super::pretty::test_ns1::Bar> = None;
96 }
97
98 #[test]
99 fn pretty_cross_namespace_ns2_accessible() {
100 // Compile-time type check: types in test.ns2 that reference test.ns1.
101 let _: Option<super::pretty::test_ns2::consumer::Consumer> = None;
102 }
103
104 #[test]
105 fn pretty_cross_namespace_ns3_collision_accessible() {
106 // Compile-time type check: ns3 defines local Foo AND refs external Foo.
107 let _: Option<super::pretty::test_ns3::collision::Collision> = None;
108 let _: Option<super::pretty::test_ns3::collision::Foo> = None;
109 }
110
111 // -- Macro mode type accessibility (same types, different module root) --
112
113 #[test]
114 fn macro_strong_ref_accessible() {
115 let _: Option<super::macro_mode::com_atproto::repo::strong_ref::StrongRef> = None;
116 }
117
118 #[test]
119 fn macro_facet_types_accessible() {
120 let _: Option<super::macro_mode::app_bsky::richtext::facet::Facet> = None;
121 let _: Option<super::macro_mode::app_bsky::richtext::facet::Mention> = None;
122 }
123
124 #[test]
125 fn macro_label_defs_accessible() {
126 let _: Option<super::macro_mode::com_atproto::label::Label> = None;
127 }
128
129 #[test]
130 fn macro_collision_collection_accessible() {
131 let _: Option<super::macro_mode::test_collision::collection::CollectionRecord> = None;
132 let _: Option<super::macro_mode::test_collision::collection::Collection> = None;
133 }
134
135 #[test]
136 fn macro_cross_namespace_ns1_accessible() {
137 let _: Option<super::macro_mode::test_ns1::Foo> = None;
138 let _: Option<super::macro_mode::test_ns1::Bar> = None;
139 }
140
141 #[test]
142 fn macro_cross_namespace_ns2_accessible() {
143 let _: Option<super::macro_mode::test_ns2::consumer::Consumer> = None;
144 }
145
146 #[test]
147 fn macro_cross_namespace_ns3_accessible() {
148 let _: Option<super::macro_mode::test_ns3::collision::Collision> = None;
149 let _: Option<super::macro_mode::test_ns3::collision::Foo> = None;
150 }
151}