1use lean_rs::abi::nat;
9use lean_rs::abi::structure::{alloc_ctor_with_objects, take_ctor_objects, view};
10use lean_rs::abi::traits::{IntoLean, LeanAbi, TryFromLean, conversion_error, sealed};
11use lean_rs::{LeanRuntime, Obj};
12use lean_toolchain::LEAN_DIAGNOSTIC_BYTE_LIMIT_MAX;
13
14use crate::host::elaboration::LeanElabFailure;
15
16#[derive(Clone, Debug, Eq, PartialEq)]
18pub enum ModuleQuery {
19 Diagnostics,
21 TypeAt {
23 line: u32,
25 column: u32,
27 },
28 GoalAt {
30 line: u32,
32 column: u32,
34 },
35 References {
37 name: String,
39 },
40}
41
42#[derive(Clone, Debug, Eq, PartialEq)]
49pub struct ModuleQueryOutputBudgets {
50 pub per_field_bytes: u32,
52 pub total_bytes: u32,
54}
55
56impl Default for ModuleQueryOutputBudgets {
57 fn default() -> Self {
58 Self {
59 per_field_bytes: 8 * 1024,
60 total_bytes: 64 * 1024,
61 }
62 }
63}
64
65impl ModuleQueryOutputBudgets {
66 #[must_use]
68 pub fn new() -> Self {
69 Self::default()
70 }
71
72 #[must_use]
75 pub fn per_field_bytes(mut self, bytes: u32) -> Self {
76 self.per_field_bytes = clamp_output_budget(bytes);
77 self
78 }
79
80 #[must_use]
83 pub fn total_bytes(mut self, bytes: u32) -> Self {
84 self.total_bytes = clamp_output_budget(bytes);
85 self
86 }
87
88 fn normalized(self) -> Self {
89 Self {
90 per_field_bytes: clamp_output_budget(self.per_field_bytes),
91 total_bytes: clamp_output_budget(self.total_bytes),
92 }
93 }
94}
95
96fn clamp_output_budget(bytes: u32) -> u32 {
97 let max = u32::try_from(LEAN_DIAGNOSTIC_BYTE_LIMIT_MAX).unwrap_or(u32::MAX);
98 bytes.min(max)
99}
100
101#[derive(Clone, Debug, Default, Eq, PartialEq)]
103pub enum ProofPositionSelector {
104 #[default]
106 Default,
107 Index { index: u32 },
109 AfterText { text: String, occurrence: Option<u32> },
111 Entry,
115}
116
117#[derive(Clone, Debug, Eq, PartialEq)]
119pub enum ProofEditTarget {
120 Declaration {
121 name: String,
122 position: ProofPositionSelector,
123 },
124}
125
126#[derive(Clone, Debug, Eq, PartialEq)]
128pub struct ProofCandidate {
129 pub id: String,
130 pub text: String,
131}
132
133#[derive(Clone, Debug, Eq, PartialEq)]
135pub struct ProofAttemptRequest {
136 pub source: String,
137 pub edit: ProofEditTarget,
138 pub candidates: Vec<ProofCandidate>,
139 pub budgets: ModuleQueryOutputBudgets,
140}
141
142#[derive(Clone, Copy, Debug, Eq, PartialEq)]
144pub enum ProofAttemptStatus {
145 Closed,
146 Progressed,
147 Failed,
148 Timeout,
149 BudgetExceeded,
150 NotAttempted,
151 Unsupported,
152}
153
154#[derive(Clone, Debug)]
156pub struct ProofAttemptRow {
157 pub id: String,
158 pub status: ProofAttemptStatus,
159 pub candidate_text: RenderedInfo,
160 pub diagnostics: LeanElabFailure,
161 pub downstream_diagnostics: LeanElabFailure,
162 pub goals: Vec<RenderedInfo>,
163 pub declaration: Option<DeclarationTargetInfo>,
164 pub proof_position: Option<ProofPositionSummary>,
165 pub output_truncated: bool,
166}
167
168#[derive(Clone, Debug, Eq, PartialEq)]
170pub struct ProofPositionSummary {
171 pub index: u32,
172 pub tactic: RenderedInfo,
173}
174
175#[derive(Clone, Debug, Eq, PartialEq)]
177pub struct ProofBoundaryCandidate {
178 pub index: u32,
179 pub kind: String,
180 pub source: ModuleSourceSpan,
181 pub excerpt: RenderedInfo,
182}
183
184#[derive(Clone, Debug)]
186pub struct ProofAttemptEnvelope {
187 pub candidates: Vec<ProofAttemptRow>,
188 pub candidate_limit: u32,
189 pub candidates_truncated: bool,
190 pub entry_goals: Vec<RenderedInfo>,
197 pub locals: Vec<LocalInfo>,
203}
204
205#[derive(Clone, Debug)]
207pub enum ProofAttemptOutcome {
208 Ok {
209 result: ProofAttemptEnvelope,
210 imports: Vec<String>,
211 },
212 MissingImports {
213 result: ProofAttemptEnvelope,
214 imports: Vec<String>,
215 missing: Vec<String>,
216 },
217 HeaderParseFailed {
218 diagnostics: LeanElabFailure,
219 },
220 Unsupported,
221}
222
223#[derive(Clone, Debug, Eq, PartialEq)]
225pub enum DeclarationVerificationTarget {
226 Name { name: String },
227 Span { span: ModuleSourceSpan },
228}
229
230#[derive(Clone, Copy, Debug, Eq, PartialEq)]
232pub enum SorryPolicy {
233 Allow,
234 Deny,
235}
236
237#[derive(Clone, Debug, Eq, PartialEq)]
239pub struct DeclarationVerificationRequest {
240 pub source: String,
241 pub target: DeclarationVerificationTarget,
242 pub sorry_policy: SorryPolicy,
243 pub report_axioms: bool,
244 pub budgets: ModuleQueryOutputBudgets,
245}
246
247#[derive(Clone, Debug, Eq, PartialEq)]
249pub struct DeclarationVerificationBatchItem {
250 pub id: String,
251 pub target: DeclarationVerificationTarget,
252}
253
254#[derive(Clone, Debug, Eq, PartialEq)]
256pub struct DeclarationVerificationBatchRequest {
257 pub source: String,
258 pub targets: Vec<DeclarationVerificationBatchItem>,
259 pub sorry_policy: SorryPolicy,
260 pub report_axioms: bool,
261 pub budgets: ModuleQueryOutputBudgets,
262}
263
264#[derive(Clone, Copy, Debug, Eq, PartialEq)]
266pub enum DeclarationVerificationStatus {
267 Accepted,
268 Rejected,
269 NotFound,
270 Ambiguous,
271 Timeout,
272 BudgetExceeded,
273 Unsupported,
274 NeedsBuild,
275}
276
277#[derive(Clone, Debug)]
279#[allow(
280 clippy::struct_excessive_bools,
281 reason = "verification booleans are independent wire facts for policy decisions"
282)]
283pub struct DeclarationVerificationFacts {
284 pub target: Option<DeclarationTargetInfo>,
285 pub diagnostics: LeanElabFailure,
286 pub unresolved_goals: Vec<RenderedInfo>,
287 pub contains_sorry: bool,
288 pub contains_admit: bool,
289 pub contains_sorry_ax: bool,
290 pub axioms: Vec<String>,
291 pub axioms_truncated: bool,
292 pub output_truncated: bool,
293 pub candidates: Vec<DeclarationTargetInfo>,
294 pub axioms_available: bool,
295}
296
297#[derive(Clone, Debug)]
299pub enum DeclarationVerificationOutcome {
300 Ok {
301 status: DeclarationVerificationStatus,
302 facts: Box<DeclarationVerificationFacts>,
303 imports: Vec<String>,
304 },
305 MissingImports {
306 status: DeclarationVerificationStatus,
307 facts: Box<DeclarationVerificationFacts>,
308 imports: Vec<String>,
309 missing: Vec<String>,
310 },
311 HeaderParseFailed {
312 diagnostics: LeanElabFailure,
313 },
314 Unsupported,
315}
316
317#[derive(Clone, Debug)]
319pub struct DeclarationVerificationBatchRow {
320 pub id: String,
321 pub target: DeclarationVerificationTarget,
322 pub status: DeclarationVerificationStatus,
323 pub facts: Box<DeclarationVerificationFacts>,
324}
325
326#[derive(Clone, Debug)]
328pub enum DeclarationVerificationBatchOutcome {
329 Ok {
330 results: Vec<DeclarationVerificationBatchRow>,
331 imports: Vec<String>,
332 },
333 MissingImports {
334 results: Vec<DeclarationVerificationBatchRow>,
335 imports: Vec<String>,
336 missing: Vec<String>,
337 },
338 HeaderParseFailed {
339 diagnostics: LeanElabFailure,
340 },
341 Unsupported,
342}
343
344#[derive(Clone, Debug, Eq, PartialEq)]
346pub enum ModuleQuerySelector {
347 Diagnostics {
348 id: String,
349 },
350 ProofState {
351 id: String,
352 line: u32,
353 column: u32,
354 },
355 ProofStateInDeclaration {
356 id: String,
357 declaration: String,
358 position: ProofPositionSelector,
359 locals_raw: bool,
362 },
363 TypeAt {
364 id: String,
365 line: u32,
366 column: u32,
367 },
368 References {
369 id: String,
370 name: String,
371 },
372 DeclarationTarget {
373 id: String,
374 name: Option<String>,
375 line: Option<u32>,
376 column: Option<u32>,
377 },
378 SurroundingDeclaration {
379 id: String,
380 line: u32,
381 column: u32,
382 },
383 DeclarationOutline {
384 id: String,
385 },
386}
387
388impl ModuleQuerySelector {
389 #[must_use]
390 pub fn id(&self) -> &str {
391 match self {
392 Self::Diagnostics { id }
393 | Self::ProofState { id, .. }
394 | Self::ProofStateInDeclaration { id, .. }
395 | Self::TypeAt { id, .. }
396 | Self::References { id, .. }
397 | Self::DeclarationTarget { id, .. }
398 | Self::SurroundingDeclaration { id, .. } => id,
399 Self::DeclarationOutline { id } => id,
400 }
401 }
402}
403
404impl<'lean> IntoLean<'lean> for ModuleQuery {
405 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
406 match self {
407 Self::Diagnostics => 0u8.into_lean(runtime),
408 Self::TypeAt { line, column } => {
409 alloc_ctor_with_objects(runtime, 1, [line.into_lean(runtime), column.into_lean(runtime)])
410 }
411 Self::GoalAt { line, column } => {
412 alloc_ctor_with_objects(runtime, 2, [line.into_lean(runtime), column.into_lean(runtime)])
413 }
414 Self::References { name } => alloc_ctor_with_objects(runtime, 3, [name.into_lean(runtime)]),
415 }
416 }
417}
418
419impl<'lean> IntoLean<'lean> for ModuleQueryOutputBudgets {
420 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
421 let normalized = self.normalized();
422 alloc_ctor_with_objects(
423 runtime,
424 0,
425 [
426 normalized.per_field_bytes.into_lean(runtime),
427 normalized.total_bytes.into_lean(runtime),
428 ],
429 )
430 }
431}
432
433impl sealed::SealedAbi for ModuleQueryOutputBudgets {}
434
435impl<'lean> LeanAbi<'lean> for ModuleQueryOutputBudgets {
436 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
437
438 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
439 self.into_lean(runtime).into_raw()
440 }
441
442 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
443 Err(conversion_error(
444 "ModuleQueryOutputBudgets cannot decode a Lean call result; it is an argument-only type",
445 ))
446 }
447}
448
449impl sealed::SealedAbi for &ModuleQueryOutputBudgets {}
450
451impl<'lean> LeanAbi<'lean> for &ModuleQueryOutputBudgets {
452 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
453
454 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
455 self.clone().into_lean(runtime).into_raw()
456 }
457
458 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
459 Err(conversion_error(
460 "&ModuleQueryOutputBudgets cannot decode a Lean call result; use ModuleQueryOutputBudgets for owned values",
461 ))
462 }
463}
464
465impl<'lean> IntoLean<'lean> for ModuleQuerySelector {
466 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
467 match self {
468 Self::Diagnostics { id } => alloc_ctor_with_objects(runtime, 0, [id.into_lean(runtime)]),
469 Self::ProofState { id, line, column } => alloc_ctor_with_objects(
470 runtime,
471 1,
472 [
473 id.into_lean(runtime),
474 line.into_lean(runtime),
475 column.into_lean(runtime),
476 ],
477 ),
478 Self::TypeAt { id, line, column } => alloc_ctor_with_objects(
479 runtime,
480 2,
481 [
482 id.into_lean(runtime),
483 line.into_lean(runtime),
484 column.into_lean(runtime),
485 ],
486 ),
487 Self::References { id, name } => {
488 alloc_ctor_with_objects(runtime, 3, [id.into_lean(runtime), name.into_lean(runtime)])
489 }
490 Self::DeclarationTarget { id, name, line, column } => alloc_ctor_with_objects(
491 runtime,
492 4,
493 [
494 id.into_lean(runtime),
495 name.into_lean(runtime),
496 line.into_lean(runtime),
497 column.into_lean(runtime),
498 ],
499 ),
500 Self::SurroundingDeclaration { id, line, column } => alloc_ctor_with_objects(
501 runtime,
502 5,
503 [
504 id.into_lean(runtime),
505 line.into_lean(runtime),
506 column.into_lean(runtime),
507 ],
508 ),
509 Self::ProofStateInDeclaration {
510 id,
511 declaration,
512 position,
513 locals_raw,
514 } => alloc_ctor_with_objects(
515 runtime,
516 6,
517 [
518 id.into_lean(runtime),
519 declaration.into_lean(runtime),
520 position.into_lean(runtime),
521 u32::from(locals_raw).into_lean(runtime),
522 ],
523 ),
524 Self::DeclarationOutline { id } => alloc_ctor_with_objects(runtime, 7, [id.into_lean(runtime)]),
525 }
526 }
527}
528
529impl<'lean> TryFromLean<'lean> for ModuleQuerySelector {
530 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
531 drop(obj);
532 Err(conversion_error(
533 "ModuleQuerySelector cannot decode a Lean call result; it is an argument-only type",
534 ))
535 }
536}
537
538impl sealed::SealedAbi for ModuleQuerySelector {}
539
540impl<'lean> LeanAbi<'lean> for ModuleQuerySelector {
541 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
542
543 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
544 self.into_lean(runtime).into_raw()
545 }
546
547 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
548 Err(conversion_error(
549 "ModuleQuerySelector cannot decode a Lean call result; it is an argument-only type",
550 ))
551 }
552}
553
554impl sealed::SealedAbi for ModuleQuery {}
555
556impl<'lean> LeanAbi<'lean> for ModuleQuery {
557 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
558
559 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
560 self.into_lean(runtime).into_raw()
561 }
562
563 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
564 Err(conversion_error(
565 "ModuleQuery cannot decode a Lean call result; it is an argument-only type",
566 ))
567 }
568}
569
570impl sealed::SealedAbi for &ModuleQuery {}
571
572impl<'lean> LeanAbi<'lean> for &ModuleQuery {
573 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
574
575 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
576 self.clone().into_lean(runtime).into_raw()
577 }
578
579 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
580 Err(conversion_error(
581 "&ModuleQuery cannot decode a Lean call result; use ModuleQuery for owned values",
582 ))
583 }
584}
585
586#[derive(Clone, Debug, Eq, PartialEq)]
588pub struct ModuleSourceSpan {
589 pub start_line: u32,
590 pub start_column: u32,
591 pub end_line: u32,
592 pub end_column: u32,
593}
594
595impl<'lean> TryFromLean<'lean> for ModuleSourceSpan {
596 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
597 let [sl, sc, el, ec] = take_ctor_objects::<4>(obj, 0, "ModuleSourceSpan")?;
598 Ok(Self {
599 start_line: u32::try_from_lean(sl)?,
600 start_column: u32::try_from_lean(sc)?,
601 end_line: u32::try_from_lean(el)?,
602 end_column: u32::try_from_lean(ec)?,
603 })
604 }
605}
606
607impl<'lean> IntoLean<'lean> for ModuleSourceSpan {
608 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
609 alloc_ctor_with_objects(
610 runtime,
611 0,
612 [
613 self.start_line.into_lean(runtime),
614 self.start_column.into_lean(runtime),
615 self.end_line.into_lean(runtime),
616 self.end_column.into_lean(runtime),
617 ],
618 )
619 }
620}
621
622impl<'lean> IntoLean<'lean> for ProofPositionSelector {
623 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
624 match self {
625 Self::Default => 0u8.into_lean(runtime),
626 Self::Index { index } => alloc_ctor_with_objects(runtime, 1, [index.into_lean(runtime)]),
627 Self::AfterText { text, occurrence } => {
628 alloc_ctor_with_objects(runtime, 2, [text.into_lean(runtime), occurrence.into_lean(runtime)])
629 }
630 Self::Entry => 3u8.into_lean(runtime),
631 }
632 }
633}
634
635impl<'lean> IntoLean<'lean> for ProofEditTarget {
636 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
637 match self {
638 Self::Declaration { name, position } => {
639 alloc_ctor_with_objects(runtime, 0, [name.into_lean(runtime), position.into_lean(runtime)])
640 }
641 }
642 }
643}
644
645impl<'lean> IntoLean<'lean> for ProofCandidate {
646 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
647 alloc_ctor_with_objects(runtime, 0, [self.id.into_lean(runtime), self.text.into_lean(runtime)])
648 }
649}
650
651impl<'lean> IntoLean<'lean> for ProofAttemptRequest {
652 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
653 alloc_ctor_with_objects(
654 runtime,
655 0,
656 [
657 self.source.into_lean(runtime),
658 self.edit.into_lean(runtime),
659 self.candidates.into_lean(runtime),
660 self.budgets.into_lean(runtime),
661 ],
662 )
663 }
664}
665
666impl sealed::SealedAbi for ProofAttemptRequest {}
667
668impl<'lean> LeanAbi<'lean> for ProofAttemptRequest {
669 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
670
671 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
672 self.into_lean(runtime).into_raw()
673 }
674
675 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
676 Err(conversion_error(
677 "ProofAttemptRequest cannot decode a Lean call result; it is an argument-only type",
678 ))
679 }
680}
681
682impl sealed::SealedAbi for &ProofAttemptRequest {}
683
684impl<'lean> LeanAbi<'lean> for &ProofAttemptRequest {
685 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
686
687 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
688 self.clone().into_lean(runtime).into_raw()
689 }
690
691 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
692 Err(conversion_error(
693 "&ProofAttemptRequest cannot decode a Lean call result; use ProofAttemptRequest for owned values",
694 ))
695 }
696}
697
698impl<'lean> IntoLean<'lean> for DeclarationVerificationTarget {
699 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
700 match self {
701 Self::Name { name } => alloc_ctor_with_objects(runtime, 0, [name.into_lean(runtime)]),
702 Self::Span { span } => alloc_ctor_with_objects(runtime, 1, [span.into_lean(runtime)]),
703 }
704 }
705}
706
707impl<'lean> TryFromLean<'lean> for DeclarationVerificationTarget {
708 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
709 match sum_tag(&obj)? {
710 0 => {
711 let [name] = take_ctor_objects::<1>(obj, 0, "DeclarationVerificationTarget::name")?;
712 Ok(Self::Name {
713 name: String::try_from_lean(name)?,
714 })
715 }
716 1 => {
717 let [span] = take_ctor_objects::<1>(obj, 1, "DeclarationVerificationTarget::span")?;
718 Ok(Self::Span {
719 span: ModuleSourceSpan::try_from_lean(span)?,
720 })
721 }
722 other => Err(conversion_error(format!(
723 "expected Lean DeclarationVerificationTarget ctor (tag 0..=1), found tag {other}"
724 ))),
725 }
726 }
727}
728
729impl<'lean> IntoLean<'lean> for SorryPolicy {
730 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
731 match self {
732 Self::Allow => 0u32.into_lean(runtime),
733 Self::Deny => 1u32.into_lean(runtime),
734 }
735 }
736}
737
738impl<'lean> IntoLean<'lean> for DeclarationVerificationRequest {
739 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
740 alloc_ctor_with_objects(
741 runtime,
742 0,
743 [
744 self.source.into_lean(runtime),
745 self.target.into_lean(runtime),
746 self.sorry_policy.into_lean(runtime),
747 (u32::from(self.report_axioms)).into_lean(runtime),
748 self.budgets.into_lean(runtime),
749 ],
750 )
751 }
752}
753
754impl sealed::SealedAbi for DeclarationVerificationRequest {}
755
756impl<'lean> LeanAbi<'lean> for DeclarationVerificationRequest {
757 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
758
759 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
760 self.into_lean(runtime).into_raw()
761 }
762
763 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
764 Err(conversion_error(
765 "DeclarationVerificationRequest cannot decode a Lean call result; it is an argument-only type",
766 ))
767 }
768}
769
770impl sealed::SealedAbi for &DeclarationVerificationRequest {}
771
772impl<'lean> LeanAbi<'lean> for &DeclarationVerificationRequest {
773 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
774
775 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
776 self.clone().into_lean(runtime).into_raw()
777 }
778
779 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
780 Err(conversion_error(
781 "&DeclarationVerificationRequest cannot decode a Lean call result; use DeclarationVerificationRequest for owned values",
782 ))
783 }
784}
785
786impl<'lean> IntoLean<'lean> for DeclarationVerificationBatchItem {
787 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
788 alloc_ctor_with_objects(runtime, 0, [self.id.into_lean(runtime), self.target.into_lean(runtime)])
789 }
790}
791
792impl<'lean> IntoLean<'lean> for DeclarationVerificationBatchRequest {
793 fn into_lean(self, runtime: &'lean LeanRuntime) -> Obj<'lean> {
794 alloc_ctor_with_objects(
795 runtime,
796 0,
797 [
798 self.source.into_lean(runtime),
799 self.targets.into_lean(runtime),
800 self.sorry_policy.into_lean(runtime),
801 (u32::from(self.report_axioms)).into_lean(runtime),
802 self.budgets.into_lean(runtime),
803 ],
804 )
805 }
806}
807
808impl sealed::SealedAbi for DeclarationVerificationBatchRequest {}
809
810impl<'lean> LeanAbi<'lean> for DeclarationVerificationBatchRequest {
811 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
812
813 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
814 self.into_lean(runtime).into_raw()
815 }
816
817 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
818 Err(conversion_error(
819 "DeclarationVerificationBatchRequest cannot decode a Lean call result; it is an argument-only type",
820 ))
821 }
822}
823
824impl sealed::SealedAbi for &DeclarationVerificationBatchRequest {}
825
826impl<'lean> LeanAbi<'lean> for &DeclarationVerificationBatchRequest {
827 type CRepr = <Obj<'lean> as LeanAbi<'lean>>::CRepr;
828
829 fn into_c(self, runtime: &'lean LeanRuntime) -> Self::CRepr {
830 self.clone().into_lean(runtime).into_raw()
831 }
832
833 fn from_c(_c: Self::CRepr, _runtime: &'lean LeanRuntime) -> lean_rs::LeanResult<Self> {
834 Err(conversion_error(
835 "&DeclarationVerificationBatchRequest cannot decode a Lean call result; use DeclarationVerificationBatchRequest for owned values",
836 ))
837 }
838}
839
840#[derive(Clone, Debug, Eq, PartialEq)]
842pub struct RenderedInfo {
843 pub value: String,
844 pub truncated: bool,
845}
846
847impl<'lean> TryFromLean<'lean> for RenderedInfo {
848 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
849 let truncated = bool_tail(&obj, 0, "RenderedInfo.truncated")?;
850 let [value] = take_ctor_objects::<1>(obj, 0, "RenderedInfo")?;
851 Ok(Self {
852 value: String::try_from_lean(value)?,
853 truncated,
854 })
855 }
856}
857
858#[derive(Clone, Debug, Eq, PartialEq)]
860pub struct NameRefNode {
861 pub start_line: u32,
862 pub start_column: u32,
863 pub end_line: u32,
864 pub end_column: u32,
865 pub name: String,
866 pub is_binder: bool,
867}
868
869impl<'lean> TryFromLean<'lean> for NameRefNode {
870 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
871 let is_binder = bool_tail(&obj, 0, "NameRefNode.isBinder")?;
872 let [sl, sc, el, ec, nm] = take_ctor_objects::<5>(obj, 0, "NameRefNode")?;
873 Ok(Self {
874 start_line: u32::try_from_lean(sl)?,
875 start_column: u32::try_from_lean(sc)?,
876 end_line: u32::try_from_lean(el)?,
877 end_column: u32::try_from_lean(ec)?,
878 name: String::try_from_lean(nm)?,
879 is_binder,
880 })
881 }
882}
883
884#[derive(Clone, Debug, Eq, PartialEq)]
886pub enum TypeAtResult {
887 Term {
888 span: ModuleSourceSpan,
889 expr: RenderedInfo,
890 type_str: RenderedInfo,
891 expected_type: Option<RenderedInfo>,
892 },
893 NoTerm,
894}
895
896impl<'lean> TryFromLean<'lean> for TypeAtResult {
897 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
898 match sum_tag(&obj)? {
899 0 => {
900 let [span, expr, type_str, expected_type] = take_ctor_objects::<4>(obj, 0, "TypeAtResult::term")?;
901 Ok(Self::Term {
902 span: ModuleSourceSpan::try_from_lean(span)?,
903 expr: RenderedInfo::try_from_lean(expr)?,
904 type_str: RenderedInfo::try_from_lean(type_str)?,
905 expected_type: Option::<RenderedInfo>::try_from_lean(expected_type)?,
906 })
907 }
908 1 => Ok(Self::NoTerm),
909 other => Err(conversion_error(format!(
910 "expected Lean TypeAtResult ctor (tag 0..=1), found tag {other}"
911 ))),
912 }
913 }
914}
915
916#[derive(Clone, Debug, Eq, PartialEq)]
918pub enum GoalAtResult {
919 Goal {
920 span: ModuleSourceSpan,
921 goals_before: Vec<String>,
922 goals_after: Vec<String>,
923 truncated: bool,
924 },
925 NoTacticContext,
926}
927
928impl<'lean> TryFromLean<'lean> for GoalAtResult {
929 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
930 match sum_tag(&obj)? {
931 0 => {
932 let truncated = bool_tail(&obj, 0, "GoalAtResult::goal.truncated")?;
933 let [span, before, after] = take_ctor_objects::<3>(obj, 0, "GoalAtResult::goal")?;
934 Ok(Self::Goal {
935 span: ModuleSourceSpan::try_from_lean(span)?,
936 goals_before: Vec::<String>::try_from_lean(before)?,
937 goals_after: Vec::<String>::try_from_lean(after)?,
938 truncated,
939 })
940 }
941 1 => Ok(Self::NoTacticContext),
942 other => Err(conversion_error(format!(
943 "expected Lean GoalAtResult ctor (tag 0..=1), found tag {other}"
944 ))),
945 }
946 }
947}
948
949#[derive(Clone, Debug, Eq, PartialEq)]
951pub struct ReferencesResult {
952 pub references: Vec<NameRefNode>,
953 pub truncated: bool,
954}
955
956impl<'lean> TryFromLean<'lean> for ReferencesResult {
957 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
958 let truncated = bool_tail(&obj, 0, "ReferencesResult.truncated")?;
959 let [references] = take_ctor_objects::<1>(obj, 0, "ReferencesResult")?;
960 Ok(Self {
961 references: Vec::<NameRefNode>::try_from_lean(references)?,
962 truncated,
963 })
964 }
965}
966
967#[derive(Clone, Debug, Eq, PartialEq)]
969pub struct LocalInfo {
970 pub name: String,
971 pub binder_info: String,
972 pub type_str: RenderedInfo,
973 pub value: Option<RenderedInfo>,
974}
975
976impl<'lean> TryFromLean<'lean> for LocalInfo {
977 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
978 let [name, binder_info, type_str, value] = take_ctor_objects::<4>(obj, 0, "LocalInfo")?;
979 Ok(Self {
980 name: String::try_from_lean(name)?,
981 binder_info: String::try_from_lean(binder_info)?,
982 type_str: RenderedInfo::try_from_lean(type_str)?,
983 value: Option::<RenderedInfo>::try_from_lean(value)?,
984 })
985 }
986}
987
988#[derive(Clone, Debug, Eq, PartialEq)]
990pub struct DeclarationTargetInfo {
991 pub short_name: String,
992 pub declaration_name: String,
993 pub namespace_name: String,
994 pub declaration_kind: String,
995 pub declaration_span: ModuleSourceSpan,
996 pub name_span: ModuleSourceSpan,
997 pub body_span: ModuleSourceSpan,
998}
999
1000impl<'lean> TryFromLean<'lean> for DeclarationTargetInfo {
1001 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1002 let [
1003 short_name,
1004 declaration_name,
1005 namespace_name,
1006 declaration_kind,
1007 declaration_span,
1008 name_span,
1009 body_span,
1010 ] = take_ctor_objects::<7>(obj, 0, "DeclarationTargetInfo")?;
1011 Ok(Self {
1012 short_name: String::try_from_lean(short_name)?,
1013 declaration_name: String::try_from_lean(declaration_name)?,
1014 namespace_name: String::try_from_lean(namespace_name)?,
1015 declaration_kind: String::try_from_lean(declaration_kind)?,
1016 declaration_span: ModuleSourceSpan::try_from_lean(declaration_span)?,
1017 name_span: ModuleSourceSpan::try_from_lean(name_span)?,
1018 body_span: ModuleSourceSpan::try_from_lean(body_span)?,
1019 })
1020 }
1021}
1022
1023#[derive(Clone, Debug, Eq, PartialEq)]
1025pub enum DeclarationTargetResult {
1026 Target(DeclarationTargetInfo),
1027 NotFound,
1028 Ambiguous(Vec<DeclarationTargetInfo>),
1029}
1030
1031impl<'lean> TryFromLean<'lean> for DeclarationTargetResult {
1032 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1033 match sum_tag(&obj)? {
1034 0 => {
1035 let [info] = take_ctor_objects::<1>(obj, 0, "DeclarationTargetResult::target")?;
1036 Ok(Self::Target(DeclarationTargetInfo::try_from_lean(info)?))
1037 }
1038 1 => Ok(Self::NotFound),
1039 2 => {
1040 let [candidates] = take_ctor_objects::<1>(obj, 2, "DeclarationTargetResult::ambiguous")?;
1041 Ok(Self::Ambiguous(Vec::<DeclarationTargetInfo>::try_from_lean(
1042 candidates,
1043 )?))
1044 }
1045 other => Err(conversion_error(format!(
1046 "expected Lean DeclarationTargetResult ctor (tag 0..=2), found tag {other}"
1047 ))),
1048 }
1049 }
1050}
1051
1052#[derive(Clone, Debug, Eq, PartialEq)]
1054pub struct DeclarationOutlineResult {
1055 pub declarations: Vec<DeclarationTargetInfo>,
1056 pub truncated: bool,
1057}
1058
1059impl<'lean> TryFromLean<'lean> for DeclarationOutlineResult {
1060 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1061 let truncated = bool_tail(&obj, 0, "DeclarationOutlineResult.truncated")?;
1062 let [declarations] = take_ctor_objects::<1>(obj, 0, "DeclarationOutlineResult")?;
1063 Ok(Self {
1064 declarations: Vec::<DeclarationTargetInfo>::try_from_lean(declarations)?,
1065 truncated,
1066 })
1067 }
1068}
1069
1070impl<'lean> TryFromLean<'lean> for ProofAttemptStatus {
1071 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1072 Self::from_scalar(sum_tag(&obj)?)
1073 }
1074}
1075
1076impl ProofAttemptStatus {
1077 fn from_scalar(value: u8) -> lean_rs::LeanResult<Self> {
1078 match value {
1079 0 => Ok(Self::Closed),
1080 1 => Ok(Self::Progressed),
1081 2 => Ok(Self::Failed),
1082 3 => Ok(Self::Timeout),
1083 4 => Ok(Self::BudgetExceeded),
1084 5 => Ok(Self::NotAttempted),
1085 6 => Ok(Self::Unsupported),
1086 other => Err(conversion_error(format!(
1087 "expected Lean ProofAttemptStatus ctor (tag 0..=6), found tag {other}"
1088 ))),
1089 }
1090 }
1091}
1092
1093impl<'lean> TryFromLean<'lean> for ProofPositionSummary {
1094 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1095 let [index, tactic] = take_ctor_objects::<2>(obj, 0, "ProofPositionSummary")?;
1096 Ok(Self {
1097 index: u32::try_from_lean(index)?,
1098 tactic: RenderedInfo::try_from_lean(tactic)?,
1099 })
1100 }
1101}
1102
1103impl<'lean> TryFromLean<'lean> for ProofBoundaryCandidate {
1104 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1105 let [index, kind, source, excerpt] = take_ctor_objects::<4>(obj, 0, "ProofBoundaryCandidate")?;
1106 Ok(Self {
1107 index: u32::try_from_lean(index)?,
1108 kind: String::try_from_lean(kind)?,
1109 source: ModuleSourceSpan::try_from_lean(source)?,
1110 excerpt: RenderedInfo::try_from_lean(excerpt)?,
1111 })
1112 }
1113}
1114
1115impl<'lean> TryFromLean<'lean> for ProofAttemptRow {
1116 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1117 let ctor = view(&obj).ctor_shape(0, 7, "ProofAttemptRow")?;
1118 let status = ProofAttemptStatus::from_scalar(ctor.uint8(0, "ProofAttemptRow.status")?)?;
1119 let output_truncated = ctor.bool(1, "ProofAttemptRow.outputTruncated")?;
1120 let [
1121 id,
1122 candidate_text,
1123 diagnostics,
1124 downstream_diagnostics,
1125 goals,
1126 declaration,
1127 proof_position,
1128 ] = take_ctor_objects::<7>(obj, 0, "ProofAttemptRow")?;
1129 Ok(Self {
1130 id: String::try_from_lean(id)?,
1131 status,
1132 candidate_text: RenderedInfo::try_from_lean(candidate_text)?,
1133 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1134 downstream_diagnostics: LeanElabFailure::try_from_lean(downstream_diagnostics)?,
1135 goals: Vec::<RenderedInfo>::try_from_lean(goals)?,
1136 declaration: Option::<DeclarationTargetInfo>::try_from_lean(declaration)?,
1137 proof_position: Option::<ProofPositionSummary>::try_from_lean(proof_position)?,
1138 output_truncated,
1139 })
1140 }
1141}
1142
1143impl<'lean> TryFromLean<'lean> for ProofAttemptEnvelope {
1144 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1145 let candidates_truncated = bool_tail(&obj, 0, "ProofAttemptEnvelope.candidatesTruncated")?;
1146 let [candidates, candidate_limit, entry_goals, locals] =
1147 take_ctor_objects::<4>(obj, 0, "ProofAttemptEnvelope")?;
1148 Ok(Self {
1149 candidates: Vec::<ProofAttemptRow>::try_from_lean(candidates)?,
1150 candidate_limit: u32::try_from_lean(candidate_limit)?,
1151 candidates_truncated,
1152 entry_goals: Vec::<RenderedInfo>::try_from_lean(entry_goals)?,
1153 locals: Vec::<LocalInfo>::try_from_lean(locals)?,
1154 })
1155 }
1156}
1157
1158impl<'lean> TryFromLean<'lean> for ProofAttemptOutcome {
1159 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1160 match sum_tag(&obj)? {
1161 0 => {
1162 let [result, imports] = take_ctor_objects::<2>(obj, 0, "ProofAttemptOutcome::ok")?;
1163 Ok(Self::Ok {
1164 result: ProofAttemptEnvelope::try_from_lean(result)?,
1165 imports: Vec::<String>::try_from_lean(imports)?,
1166 })
1167 }
1168 1 => {
1169 let [result, imports, missing] = take_ctor_objects::<3>(obj, 1, "ProofAttemptOutcome::missingImports")?;
1170 Ok(Self::MissingImports {
1171 result: ProofAttemptEnvelope::try_from_lean(result)?,
1172 imports: Vec::<String>::try_from_lean(imports)?,
1173 missing: Vec::<String>::try_from_lean(missing)?,
1174 })
1175 }
1176 2 => {
1177 let [diagnostics] = take_ctor_objects::<1>(obj, 2, "ProofAttemptOutcome::headerParseFailed")?;
1178 Ok(Self::HeaderParseFailed {
1179 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1180 })
1181 }
1182 3 => Ok(Self::Unsupported),
1183 other => Err(conversion_error(format!(
1184 "expected Lean ProofAttemptOutcome ctor (tag 0..=3), found tag {other}"
1185 ))),
1186 }
1187 }
1188}
1189
1190impl<'lean> TryFromLean<'lean> for DeclarationVerificationStatus {
1191 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1192 Self::from_scalar(sum_tag(&obj)?)
1193 }
1194}
1195
1196impl DeclarationVerificationStatus {
1197 fn from_scalar(value: u8) -> lean_rs::LeanResult<Self> {
1198 match value {
1199 0 => Ok(Self::Accepted),
1200 1 => Ok(Self::Rejected),
1201 2 => Ok(Self::NotFound),
1202 3 => Ok(Self::Ambiguous),
1203 4 => Ok(Self::Timeout),
1204 5 => Ok(Self::BudgetExceeded),
1205 6 => Ok(Self::Unsupported),
1206 7 => Ok(Self::NeedsBuild),
1207 other => Err(conversion_error(format!(
1208 "expected Lean DeclarationVerificationStatus ctor (tag 0..=7), found tag {other}"
1209 ))),
1210 }
1211 }
1212}
1213
1214impl<'lean> TryFromLean<'lean> for DeclarationVerificationFacts {
1215 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1216 let contains_sorry = bool_tail(&obj, 0, "DeclarationVerificationFacts.containsSorry")?;
1217 let contains_admit = bool_tail(&obj, 1, "DeclarationVerificationFacts.containsAdmit")?;
1218 let contains_sorry_ax = bool_tail(&obj, 2, "DeclarationVerificationFacts.containsSorryAx")?;
1219 let axioms_truncated = bool_tail(&obj, 3, "DeclarationVerificationFacts.axiomsTruncated")?;
1220 let output_truncated = bool_tail(&obj, 4, "DeclarationVerificationFacts.outputTruncated")?;
1221 let axioms_available = bool_tail(&obj, 5, "DeclarationVerificationFacts.axiomsAvailable")?;
1222 let [target, diagnostics, unresolved_goals, axioms, candidates] =
1223 take_ctor_objects::<5>(obj, 0, "DeclarationVerificationFacts")?;
1224 Ok(Self {
1225 target: Option::<DeclarationTargetInfo>::try_from_lean(target)?,
1226 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1227 unresolved_goals: Vec::<RenderedInfo>::try_from_lean(unresolved_goals)?,
1228 contains_sorry,
1229 contains_admit,
1230 contains_sorry_ax,
1231 axioms: Vec::<String>::try_from_lean(axioms)?,
1232 axioms_truncated,
1233 output_truncated,
1234 candidates: Vec::<DeclarationTargetInfo>::try_from_lean(candidates)?,
1235 axioms_available,
1236 })
1237 }
1238}
1239
1240impl<'lean> TryFromLean<'lean> for DeclarationVerificationOutcome {
1241 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1242 match sum_tag(&obj)? {
1243 0 => {
1244 let ctor = view(&obj).ctor_shape(0, 2, "DeclarationVerificationOutcome::ok")?;
1245 let status = DeclarationVerificationStatus::from_scalar(
1246 ctor.uint8(0, "DeclarationVerificationOutcome::ok.status")?,
1247 )?;
1248 let [facts, imports] = take_ctor_objects::<2>(obj, 0, "DeclarationVerificationOutcome::ok")?;
1249 Ok(Self::Ok {
1250 status,
1251 facts: Box::new(DeclarationVerificationFacts::try_from_lean(facts)?),
1252 imports: Vec::<String>::try_from_lean(imports)?,
1253 })
1254 }
1255 1 => {
1256 let ctor = view(&obj).ctor_shape(1, 3, "DeclarationVerificationOutcome::missingImports")?;
1257 let status = DeclarationVerificationStatus::from_scalar(
1258 ctor.uint8(0, "DeclarationVerificationOutcome::missingImports.status")?,
1259 )?;
1260 let [facts, imports, missing] =
1261 take_ctor_objects::<3>(obj, 1, "DeclarationVerificationOutcome::missingImports")?;
1262 Ok(Self::MissingImports {
1263 status,
1264 facts: Box::new(DeclarationVerificationFacts::try_from_lean(facts)?),
1265 imports: Vec::<String>::try_from_lean(imports)?,
1266 missing: Vec::<String>::try_from_lean(missing)?,
1267 })
1268 }
1269 2 => {
1270 let [diagnostics] =
1271 take_ctor_objects::<1>(obj, 2, "DeclarationVerificationOutcome::headerParseFailed")?;
1272 Ok(Self::HeaderParseFailed {
1273 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1274 })
1275 }
1276 3 => Ok(Self::Unsupported),
1277 other => Err(conversion_error(format!(
1278 "expected Lean DeclarationVerificationOutcome ctor (tag 0..=3), found tag {other}"
1279 ))),
1280 }
1281 }
1282}
1283
1284impl<'lean> TryFromLean<'lean> for DeclarationVerificationBatchRow {
1285 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1286 let ctor = view(&obj).ctor_shape(0, 3, "DeclarationVerificationBatchRow")?;
1287 let status =
1288 DeclarationVerificationStatus::from_scalar(ctor.uint8(0, "DeclarationVerificationBatchRow.status")?)?;
1289 let [id, target, facts] = take_ctor_objects::<3>(obj, 0, "DeclarationVerificationBatchRow")?;
1290 Ok(Self {
1291 id: String::try_from_lean(id)?,
1292 target: DeclarationVerificationTarget::try_from_lean(target)?,
1293 status,
1294 facts: Box::new(DeclarationVerificationFacts::try_from_lean(facts)?),
1295 })
1296 }
1297}
1298
1299impl<'lean> TryFromLean<'lean> for DeclarationVerificationBatchOutcome {
1300 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1301 match sum_tag(&obj)? {
1302 0 => {
1303 let [results, imports] = take_ctor_objects::<2>(obj, 0, "DeclarationVerificationBatchOutcome::ok")?;
1304 Ok(Self::Ok {
1305 results: Vec::<DeclarationVerificationBatchRow>::try_from_lean(results)?,
1306 imports: Vec::<String>::try_from_lean(imports)?,
1307 })
1308 }
1309 1 => {
1310 let [results, imports, missing] =
1311 take_ctor_objects::<3>(obj, 1, "DeclarationVerificationBatchOutcome::missingImports")?;
1312 Ok(Self::MissingImports {
1313 results: Vec::<DeclarationVerificationBatchRow>::try_from_lean(results)?,
1314 imports: Vec::<String>::try_from_lean(imports)?,
1315 missing: Vec::<String>::try_from_lean(missing)?,
1316 })
1317 }
1318 2 => {
1319 let [diagnostics] =
1320 take_ctor_objects::<1>(obj, 2, "DeclarationVerificationBatchOutcome::headerParseFailed")?;
1321 Ok(Self::HeaderParseFailed {
1322 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1323 })
1324 }
1325 3 => Ok(Self::Unsupported),
1326 other => Err(conversion_error(format!(
1327 "expected Lean DeclarationVerificationBatchOutcome ctor (tag 0..=3), found tag {other}"
1328 ))),
1329 }
1330 }
1331}
1332
1333#[derive(Clone, Debug, Eq, PartialEq)]
1335pub struct ProofStateInfo {
1336 pub declaration_name: Option<String>,
1337 pub namespace_name: String,
1338 pub safe_edit: Option<DeclarationTargetInfo>,
1339 pub span: ModuleSourceSpan,
1340 pub goals_before: Vec<String>,
1341 pub goals_after: Vec<String>,
1342 pub locals: Vec<LocalInfo>,
1343 pub expected_type: Option<RenderedInfo>,
1344 pub truncated: bool,
1345 pub proof_boundaries: Vec<ProofBoundaryCandidate>,
1346 pub proof_boundaries_truncated: bool,
1347}
1348
1349impl<'lean> TryFromLean<'lean> for ProofStateInfo {
1350 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1351 let truncated = bool_tail(&obj, 0, "ProofStateInfo.truncated")?;
1352 let proof_boundaries_truncated = bool_tail(&obj, 1, "ProofStateInfo.proofBoundariesTruncated")?;
1353 let [
1354 declaration_name,
1355 namespace_name,
1356 safe_edit,
1357 span,
1358 goals_before,
1359 goals_after,
1360 locals,
1361 expected_type,
1362 proof_boundaries,
1363 ] = take_ctor_objects::<9>(obj, 0, "ProofStateInfo")?;
1364 Ok(Self {
1365 declaration_name: Option::<String>::try_from_lean(declaration_name)?,
1366 namespace_name: String::try_from_lean(namespace_name)?,
1367 safe_edit: Option::<DeclarationTargetInfo>::try_from_lean(safe_edit)?,
1368 span: ModuleSourceSpan::try_from_lean(span)?,
1369 goals_before: Vec::<String>::try_from_lean(goals_before)?,
1370 goals_after: Vec::<String>::try_from_lean(goals_after)?,
1371 locals: Vec::<LocalInfo>::try_from_lean(locals)?,
1372 expected_type: Option::<RenderedInfo>::try_from_lean(expected_type)?,
1373 truncated,
1374 proof_boundaries: Vec::<ProofBoundaryCandidate>::try_from_lean(proof_boundaries)?,
1375 proof_boundaries_truncated,
1376 })
1377 }
1378}
1379
1380#[derive(Clone, Debug, Eq, PartialEq)]
1382pub enum ProofStateResult {
1383 State(Box<ProofStateInfo>),
1384 Unavailable {
1385 message: String,
1386 proof_boundaries: Vec<ProofBoundaryCandidate>,
1387 proof_boundaries_truncated: bool,
1388 },
1389 Ambiguous {
1390 candidates: Vec<DeclarationTargetInfo>,
1391 },
1392 NeedsBuild {
1393 missing: Vec<String>,
1394 },
1395}
1396
1397impl<'lean> TryFromLean<'lean> for ProofStateResult {
1398 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1399 match sum_tag(&obj)? {
1400 0 => {
1401 let [info] = take_ctor_objects::<1>(obj, 0, "ProofStateResult::state")?;
1402 Ok(Self::State(Box::new(ProofStateInfo::try_from_lean(info)?)))
1403 }
1404 1 => {
1405 let proof_boundaries_truncated = view(&obj)
1406 .ctor_shape(1, 2, "ProofStateResult::unavailable")?
1407 .bool(0, "ProofStateResult::unavailable.proofBoundariesTruncated")?;
1408 let [message, proof_boundaries] = take_ctor_objects::<2>(obj, 1, "ProofStateResult::unavailable")?;
1409 Ok(Self::Unavailable {
1410 message: String::try_from_lean(message)?,
1411 proof_boundaries: Vec::<ProofBoundaryCandidate>::try_from_lean(proof_boundaries)?,
1412 proof_boundaries_truncated,
1413 })
1414 }
1415 2 => {
1416 let [candidates] = take_ctor_objects::<1>(obj, 2, "ProofStateResult::ambiguous")?;
1417 Ok(Self::Ambiguous {
1418 candidates: Vec::<DeclarationTargetInfo>::try_from_lean(candidates)?,
1419 })
1420 }
1421 3 => {
1422 let [missing] = take_ctor_objects::<1>(obj, 3, "ProofStateResult::needsBuild")?;
1423 Ok(Self::NeedsBuild {
1424 missing: Vec::<String>::try_from_lean(missing)?,
1425 })
1426 }
1427 other => Err(conversion_error(format!(
1428 "expected Lean ProofStateResult ctor (tag 0..=3), found tag {other}"
1429 ))),
1430 }
1431 }
1432}
1433
1434#[derive(Clone, Debug, Eq, PartialEq)]
1436pub enum SurroundingDeclarationResult {
1437 Declaration(DeclarationTargetInfo),
1438 None,
1439}
1440
1441impl<'lean> TryFromLean<'lean> for SurroundingDeclarationResult {
1442 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1443 match sum_tag(&obj)? {
1444 0 => {
1445 let [info] = take_ctor_objects::<1>(obj, 0, "SurroundingDeclarationResult::declaration")?;
1446 Ok(Self::Declaration(DeclarationTargetInfo::try_from_lean(info)?))
1447 }
1448 1 => Ok(Self::None),
1449 other => Err(conversion_error(format!(
1450 "expected Lean SurroundingDeclarationResult ctor (tag 0..=1), found tag {other}"
1451 ))),
1452 }
1453 }
1454}
1455
1456#[derive(Clone, Debug)]
1458pub enum ModuleQueryResult {
1459 Diagnostics(LeanElabFailure),
1460 TypeAt(TypeAtResult),
1461 GoalAt(GoalAtResult),
1462 References(ReferencesResult),
1463}
1464
1465impl<'lean> TryFromLean<'lean> for ModuleQueryResult {
1466 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1467 match sum_tag(&obj)? {
1468 0 => {
1469 let [failure] = take_ctor_objects::<1>(obj, 0, "ModuleQueryResult::diagnostics")?;
1470 Ok(Self::Diagnostics(LeanElabFailure::try_from_lean(failure)?))
1471 }
1472 1 => {
1473 let [result] = take_ctor_objects::<1>(obj, 1, "ModuleQueryResult::typeAt")?;
1474 Ok(Self::TypeAt(TypeAtResult::try_from_lean(result)?))
1475 }
1476 2 => {
1477 let [result] = take_ctor_objects::<1>(obj, 2, "ModuleQueryResult::goalAt")?;
1478 Ok(Self::GoalAt(GoalAtResult::try_from_lean(result)?))
1479 }
1480 3 => {
1481 let [result] = take_ctor_objects::<1>(obj, 3, "ModuleQueryResult::references")?;
1482 Ok(Self::References(ReferencesResult::try_from_lean(result)?))
1483 }
1484 other => Err(conversion_error(format!(
1485 "expected Lean ModuleQueryResult ctor (tag 0..=3), found tag {other}"
1486 ))),
1487 }
1488 }
1489}
1490
1491#[derive(Clone, Debug)]
1493pub enum ModuleQueryBatchResult {
1494 Diagnostics(LeanElabFailure),
1495 ProofState(ProofStateResult),
1496 TypeAt(TypeAtResult),
1497 References(ReferencesResult),
1498 DeclarationTarget(DeclarationTargetResult),
1499 SurroundingDeclaration(SurroundingDeclarationResult),
1500 DeclarationOutline(DeclarationOutlineResult),
1501}
1502
1503impl<'lean> TryFromLean<'lean> for ModuleQueryBatchResult {
1504 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1505 match sum_tag(&obj)? {
1506 0 => {
1507 let [failure] = take_ctor_objects::<1>(obj, 0, "ModuleQueryBatchResult::diagnostics")?;
1508 Ok(Self::Diagnostics(LeanElabFailure::try_from_lean(failure)?))
1509 }
1510 1 => {
1511 let [result] = take_ctor_objects::<1>(obj, 1, "ModuleQueryBatchResult::proofState")?;
1512 Ok(Self::ProofState(ProofStateResult::try_from_lean(result)?))
1513 }
1514 2 => {
1515 let [result] = take_ctor_objects::<1>(obj, 2, "ModuleQueryBatchResult::typeAt")?;
1516 Ok(Self::TypeAt(TypeAtResult::try_from_lean(result)?))
1517 }
1518 3 => {
1519 let [result] = take_ctor_objects::<1>(obj, 3, "ModuleQueryBatchResult::references")?;
1520 Ok(Self::References(ReferencesResult::try_from_lean(result)?))
1521 }
1522 4 => {
1523 let [result] = take_ctor_objects::<1>(obj, 4, "ModuleQueryBatchResult::declarationTarget")?;
1524 Ok(Self::DeclarationTarget(DeclarationTargetResult::try_from_lean(result)?))
1525 }
1526 5 => {
1527 let [result] = take_ctor_objects::<1>(obj, 5, "ModuleQueryBatchResult::surroundingDeclaration")?;
1528 Ok(Self::SurroundingDeclaration(
1529 SurroundingDeclarationResult::try_from_lean(result)?,
1530 ))
1531 }
1532 6 => {
1533 let [result] = take_ctor_objects::<1>(obj, 6, "ModuleQueryBatchResult::declarationOutline")?;
1534 Ok(Self::DeclarationOutline(DeclarationOutlineResult::try_from_lean(
1535 result,
1536 )?))
1537 }
1538 other => Err(conversion_error(format!(
1539 "expected Lean ModuleQueryBatchResult ctor (tag 0..=6), found tag {other}"
1540 ))),
1541 }
1542 }
1543}
1544
1545#[derive(Clone, Debug)]
1547pub enum ModuleQueryBatchItem {
1548 Ok {
1549 id: String,
1550 result: Box<ModuleQueryBatchResult>,
1551 },
1552 Unavailable {
1553 id: String,
1554 message: String,
1555 },
1556 BudgetExceeded {
1557 id: String,
1558 message: String,
1559 },
1560}
1561
1562impl ModuleQueryBatchItem {
1563 #[must_use]
1564 pub fn id(&self) -> &str {
1565 match self {
1566 Self::Ok { id, .. } | Self::Unavailable { id, .. } | Self::BudgetExceeded { id, .. } => id,
1567 }
1568 }
1569}
1570
1571impl<'lean> TryFromLean<'lean> for ModuleQueryBatchItem {
1572 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1573 match sum_tag(&obj)? {
1574 0 => {
1575 let [id, result] = take_ctor_objects::<2>(obj, 0, "ModuleQueryBatchItem::ok")?;
1576 Ok(Self::Ok {
1577 id: String::try_from_lean(id)?,
1578 result: Box::new(ModuleQueryBatchResult::try_from_lean(result)?),
1579 })
1580 }
1581 1 => {
1582 let [id, message] = take_ctor_objects::<2>(obj, 1, "ModuleQueryBatchItem::unavailable")?;
1583 Ok(Self::Unavailable {
1584 id: String::try_from_lean(id)?,
1585 message: String::try_from_lean(message)?,
1586 })
1587 }
1588 2 => {
1589 let [id, message] = take_ctor_objects::<2>(obj, 2, "ModuleQueryBatchItem::budgetExceeded")?;
1590 Ok(Self::BudgetExceeded {
1591 id: String::try_from_lean(id)?,
1592 message: String::try_from_lean(message)?,
1593 })
1594 }
1595 other => Err(conversion_error(format!(
1596 "expected Lean ModuleQueryBatchItem ctor (tag 0..=2), found tag {other}"
1597 ))),
1598 }
1599 }
1600}
1601
1602#[derive(Clone, Debug)]
1604pub struct ModuleQueryBatchEnvelope {
1605 pub items: Vec<ModuleQueryBatchItem>,
1606 pub total_truncated: bool,
1607}
1608
1609impl<'lean> TryFromLean<'lean> for ModuleQueryBatchEnvelope {
1610 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1611 let total_truncated = bool_tail(&obj, 0, "ModuleQueryBatchEnvelope.totalTruncated")?;
1612 let [items] = take_ctor_objects::<1>(obj, 0, "ModuleQueryBatchEnvelope")?;
1613 Ok(Self {
1614 items: Vec::<ModuleQueryBatchItem>::try_from_lean(items)?,
1615 total_truncated,
1616 })
1617 }
1618}
1619
1620#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1622pub enum ModuleQueryCacheStatus {
1623 Hit,
1624 Miss,
1625 Rebuilt,
1626 Evicted,
1627}
1628
1629impl<'lean> TryFromLean<'lean> for ModuleQueryCacheStatus {
1630 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1631 match sum_tag(&obj)? {
1632 0 => Ok(Self::Hit),
1633 1 => Ok(Self::Miss),
1634 2 => Ok(Self::Rebuilt),
1635 3 => Ok(Self::Evicted),
1636 other => Err(conversion_error(format!(
1637 "expected Lean ModuleQueryCacheStatus ctor (tag 0..=3), found tag {other}"
1638 ))),
1639 }
1640 }
1641}
1642
1643impl ModuleQueryCacheStatus {
1644 fn from_scalar_tail(byte: u8) -> lean_rs::LeanResult<Self> {
1645 match byte {
1646 0 => Ok(Self::Hit),
1647 1 => Ok(Self::Miss),
1648 2 => Ok(Self::Rebuilt),
1649 3 => Ok(Self::Evicted),
1650 other => Err(conversion_error(format!(
1651 "expected Lean ModuleQueryCacheStatus scalar tag 0..=3, found {other}"
1652 ))),
1653 }
1654 }
1655}
1656
1657#[derive(Clone, Debug, Eq, PartialEq)]
1659pub struct ModuleQueryTimings {
1660 pub header_import_micros: u64,
1661 pub elaboration_micros: u64,
1662 pub projection_micros: u64,
1663 pub rendering_micros: u64,
1664}
1665
1666impl<'lean> TryFromLean<'lean> for ModuleQueryTimings {
1667 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1668 let ctor = view(&obj).ctor_shape(0, 0, "ModuleQueryTimings")?;
1669 Ok(Self {
1670 header_import_micros: ctor.uint64(0, "ModuleQueryTimings.headerImportMicros")?,
1671 elaboration_micros: ctor.uint64(8, "ModuleQueryTimings.elaborationMicros")?,
1672 projection_micros: ctor.uint64(16, "ModuleQueryTimings.projectionMicros")?,
1673 rendering_micros: ctor.uint64(24, "ModuleQueryTimings.renderingMicros")?,
1674 })
1675 }
1676}
1677
1678#[derive(Clone, Debug, Eq, PartialEq)]
1680pub struct ModuleQueryCacheFacts {
1681 pub cache_status: ModuleQueryCacheStatus,
1682 pub timings: ModuleQueryTimings,
1683 pub output_bytes: u64,
1684 pub cache_entry_count: Option<u64>,
1685 pub cache_approx_bytes: Option<u64>,
1686}
1687
1688impl<'lean> TryFromLean<'lean> for ModuleQueryCacheFacts {
1689 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1690 let ctor = view(&obj).ctor_shape(0, 3, "ModuleQueryCacheFacts")?;
1691 let output_bytes = ctor.uint64(0, "ModuleQueryCacheFacts.outputBytes")?;
1692 let cache_status = ctor.uint8(8, "ModuleQueryCacheFacts.cacheStatus")?;
1693 let [timings, cache_entry_count, cache_approx_bytes] = take_ctor_objects::<3>(obj, 0, "ModuleQueryCacheFacts")?;
1694 Ok(Self {
1695 cache_status: ModuleQueryCacheStatus::from_scalar_tail(cache_status)?,
1696 timings: ModuleQueryTimings::try_from_lean(timings)?,
1697 output_bytes,
1698 cache_entry_count: option_nat_u64(cache_entry_count)?,
1699 cache_approx_bytes: option_nat_u64(cache_approx_bytes)?,
1700 })
1701 }
1702}
1703
1704#[derive(Clone, Debug, Eq, PartialEq)]
1706pub struct ModuleQueryCachePolicy {
1707 pub file_identity: String,
1708 pub key: String,
1709 pub max_entries: u64,
1710 pub ttl_millis: u64,
1711 pub max_bytes: u64,
1712}
1713
1714#[derive(Clone, Debug)]
1716pub enum ModuleQueryOutcome {
1717 Ok {
1718 result: ModuleQueryResult,
1719 imports: Vec<String>,
1720 },
1721 MissingImports {
1722 result: ModuleQueryResult,
1723 imports: Vec<String>,
1724 missing: Vec<String>,
1725 },
1726 HeaderParseFailed {
1727 diagnostics: LeanElabFailure,
1728 },
1729 Unsupported,
1730}
1731
1732impl<'lean> TryFromLean<'lean> for ModuleQueryOutcome {
1733 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1734 match sum_tag(&obj)? {
1735 0 => {
1736 let [result, imports] = take_ctor_objects::<2>(obj, 0, "ModuleQueryOutcome::ok")?;
1737 Ok(Self::Ok {
1738 result: ModuleQueryResult::try_from_lean(result)?,
1739 imports: Vec::<String>::try_from_lean(imports)?,
1740 })
1741 }
1742 1 => {
1743 let [result, imports, missing] = take_ctor_objects::<3>(obj, 1, "ModuleQueryOutcome::missingImports")?;
1744 Ok(Self::MissingImports {
1745 result: ModuleQueryResult::try_from_lean(result)?,
1746 imports: Vec::<String>::try_from_lean(imports)?,
1747 missing: Vec::<String>::try_from_lean(missing)?,
1748 })
1749 }
1750 2 => {
1751 let [diagnostics] = take_ctor_objects::<1>(obj, 2, "ModuleQueryOutcome::headerParseFailed")?;
1752 Ok(Self::HeaderParseFailed {
1753 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1754 })
1755 }
1756 3 => Ok(Self::Unsupported),
1757 other => Err(conversion_error(format!(
1758 "expected Lean ModuleQueryOutcome ctor (tag 0..=3), found tag {other}"
1759 ))),
1760 }
1761 }
1762}
1763
1764#[derive(Clone, Debug)]
1766pub enum ModuleQueryBatchOutcome {
1767 Ok {
1768 result: ModuleQueryBatchEnvelope,
1769 imports: Vec<String>,
1770 },
1771 MissingImports {
1772 result: ModuleQueryBatchEnvelope,
1773 imports: Vec<String>,
1774 missing: Vec<String>,
1775 },
1776 HeaderParseFailed {
1777 diagnostics: LeanElabFailure,
1778 },
1779 Unsupported,
1780}
1781
1782impl<'lean> TryFromLean<'lean> for ModuleQueryBatchOutcome {
1783 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1784 match sum_tag(&obj)? {
1785 0 => {
1786 let [result, imports] = take_ctor_objects::<2>(obj, 0, "ModuleQueryBatchOutcome::ok")?;
1787 Ok(Self::Ok {
1788 result: ModuleQueryBatchEnvelope::try_from_lean(result)?,
1789 imports: Vec::<String>::try_from_lean(imports)?,
1790 })
1791 }
1792 1 => {
1793 let [result, imports, missing] =
1794 take_ctor_objects::<3>(obj, 1, "ModuleQueryBatchOutcome::missingImports")?;
1795 Ok(Self::MissingImports {
1796 result: ModuleQueryBatchEnvelope::try_from_lean(result)?,
1797 imports: Vec::<String>::try_from_lean(imports)?,
1798 missing: Vec::<String>::try_from_lean(missing)?,
1799 })
1800 }
1801 2 => {
1802 let [diagnostics] = take_ctor_objects::<1>(obj, 2, "ModuleQueryBatchOutcome::headerParseFailed")?;
1803 Ok(Self::HeaderParseFailed {
1804 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1805 })
1806 }
1807 3 => Ok(Self::Unsupported),
1808 other => Err(conversion_error(format!(
1809 "expected Lean ModuleQueryBatchOutcome ctor (tag 0..=3), found tag {other}"
1810 ))),
1811 }
1812 }
1813}
1814
1815#[derive(Clone, Debug)]
1817pub enum ModuleQueryBatchCachedOutcome {
1818 Ok {
1819 result: ModuleQueryBatchEnvelope,
1820 imports: Vec<String>,
1821 facts: ModuleQueryCacheFacts,
1822 },
1823 MissingImports {
1824 result: ModuleQueryBatchEnvelope,
1825 imports: Vec<String>,
1826 missing: Vec<String>,
1827 facts: ModuleQueryCacheFacts,
1828 },
1829 HeaderParseFailed {
1830 diagnostics: LeanElabFailure,
1831 facts: ModuleQueryCacheFacts,
1832 },
1833 Unsupported,
1834}
1835
1836impl<'lean> TryFromLean<'lean> for ModuleQueryBatchCachedOutcome {
1837 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1838 match sum_tag(&obj)? {
1839 0 => {
1840 let [result, imports, facts] = take_ctor_objects::<3>(obj, 0, "ModuleQueryBatchCachedOutcome::ok")?;
1841 Ok(Self::Ok {
1842 result: ModuleQueryBatchEnvelope::try_from_lean(result)?,
1843 imports: Vec::<String>::try_from_lean(imports)?,
1844 facts: ModuleQueryCacheFacts::try_from_lean(facts)?,
1845 })
1846 }
1847 1 => {
1848 let [result, imports, missing, facts] =
1849 take_ctor_objects::<4>(obj, 1, "ModuleQueryBatchCachedOutcome::missingImports")?;
1850 Ok(Self::MissingImports {
1851 result: ModuleQueryBatchEnvelope::try_from_lean(result)?,
1852 imports: Vec::<String>::try_from_lean(imports)?,
1853 missing: Vec::<String>::try_from_lean(missing)?,
1854 facts: ModuleQueryCacheFacts::try_from_lean(facts)?,
1855 })
1856 }
1857 2 => {
1858 let [diagnostics, facts] =
1859 take_ctor_objects::<2>(obj, 2, "ModuleQueryBatchCachedOutcome::headerParseFailed")?;
1860 Ok(Self::HeaderParseFailed {
1861 diagnostics: LeanElabFailure::try_from_lean(diagnostics)?,
1862 facts: ModuleQueryCacheFacts::try_from_lean(facts)?,
1863 })
1864 }
1865 3 => Ok(Self::Unsupported),
1866 other => Err(conversion_error(format!(
1867 "expected Lean ModuleQueryBatchCachedOutcome ctor (tag 0..=3), found tag {other}"
1868 ))),
1869 }
1870 }
1871}
1872
1873#[derive(Clone, Debug, Eq, PartialEq)]
1875pub struct ModuleSnapshotCacheClearResult {
1876 pub entries_cleared: u64,
1877 pub approx_bytes_cleared: u64,
1878}
1879
1880impl<'lean> TryFromLean<'lean> for ModuleSnapshotCacheClearResult {
1881 fn try_from_lean(obj: Obj<'lean>) -> lean_rs::LeanResult<Self> {
1882 let ctor = view(&obj).ctor_shape(0, 0, "ModuleSnapshotCacheClearResult")?;
1883 Ok(Self {
1884 entries_cleared: ctor.uint64(0, "ModuleSnapshotCacheClearResult.entriesCleared")?,
1885 approx_bytes_cleared: ctor.uint64(8, "ModuleSnapshotCacheClearResult.approxBytesCleared")?,
1886 })
1887 }
1888}
1889
1890fn option_nat_u64(obj: Obj<'_>) -> lean_rs::LeanResult<Option<u64>> {
1891 match sum_tag(&obj)? {
1892 0 => Ok(None),
1893 1 => {
1894 let [value] = take_ctor_objects::<1>(obj, 1, "Option::some Nat")?;
1895 Ok(Some(nat::try_to_u64(value)?))
1896 }
1897 other => Err(conversion_error(format!(
1898 "expected Lean Option Nat ctor (tag 0..=1), found tag {other}"
1899 ))),
1900 }
1901}
1902
1903fn bool_tail(obj: &Obj<'_>, offset: u32, label: &str) -> lean_rs::LeanResult<bool> {
1904 let ctor = view(obj).ctor()?;
1905 if ctor.tag() != 0 {
1906 return Err(conversion_error(format!(
1907 "expected Lean {label} constructor tag 0, found tag {}",
1908 ctor.tag()
1909 )));
1910 }
1911 ctor.bool(offset, label)
1912}
1913
1914fn sum_tag(obj: &Obj<'_>) -> lean_rs::LeanResult<u8> {
1915 view(obj).sum_tag()
1916}
1917
1918#[cfg(test)]
1919mod tests {
1920 use super::*;
1921
1922 #[test]
1923 fn module_query_output_budget_defaults_match_policy() {
1924 let budgets = ModuleQueryOutputBudgets::new();
1925 assert_eq!(budgets.per_field_bytes, 8 * 1024);
1926 assert_eq!(budgets.total_bytes, 64 * 1024);
1927 }
1928
1929 #[test]
1930 fn module_query_output_budget_setters_saturate() {
1931 let budgets = ModuleQueryOutputBudgets::new()
1932 .per_field_bytes(u32::MAX)
1933 .total_bytes(u32::MAX);
1934 let max = clamp_output_budget(u32::MAX);
1935 assert_eq!(budgets.per_field_bytes, max);
1936 assert_eq!(budgets.total_bytes, max);
1937 }
1938
1939 #[test]
1940 fn module_query_output_budget_normalization_clamps_struct_literals() {
1941 let budgets = ModuleQueryOutputBudgets {
1942 per_field_bytes: u32::MAX,
1943 total_bytes: u32::MAX,
1944 }
1945 .normalized();
1946 let max = clamp_output_budget(u32::MAX);
1947 assert_eq!(budgets.per_field_bytes, max);
1948 assert_eq!(budgets.total_bytes, max);
1949 }
1950}