1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//! This crate contains procedural macros that are used to generate code for the TypeSpec SDK.
use ;
extern crate proc_macro;
type Result<T> = Result;
// NOTE: Proc macros must appear in the root of the crate. Just re-exporting them with `pub use` is **not sufficient**.
// So, all the top-level entry functions for the proc macros will appear here, but they just call inner "impl" functions in the modules.
/// Defines the function signature expected by run_derive_macro
type DeriveImpl = fn ;
/// Runs the provided derive macro implementation, automatically generating errors if it returns errors.
/// Derive to help prevent leaking personally identifiable information (PII) that deriving [`Debug`](std::fmt::Debug) might otherwise.
///
/// `SafeDebug` is not a trait and cannot be implemented, nor should you derive `Debug` explicitly.
/// Only when you derive `SafeDebug` will types help prevent leaking PII because, by default, only the type name is printed.
/// Only when you enable the `debug` feature will it derive `Debug` normally.
///
/// You can attribute types, fields, and variants with `#[safe(true)]` or `#[safe(false)]` to optionally show or hide members.
/// The default is that no members are shown. The inner most `#[safe(..)]` attribute determines whether to show or hide a member.
///
/// # Examples
///
/// ```
/// # use typespec_macros::SafeDebug;
/// #[derive(SafeDebug)]
/// struct Person {
/// name: String,
/// }
///
/// let person = Person {
/// name: "Kelly Smith".to_string(),
/// };
/// if cfg!(feature = "debug") {
/// assert_eq!(format!("{person:?}"), r#"Person { name: "Kelly Smith" }"#);
/// } else {
/// assert_eq!(format!("{person:?}"), "Person { .. }");
/// }
/// ```
///
/// Using the `#[safe(..)]` attribute, you can selectively show or hide members.
/// The default, when not present or inherited, is to always hide members unless the `debug` feature is enabled.
///
/// ```
/// # use typespec_macros::SafeDebug;
/// use std::ops::Range;
///
/// #[derive(SafeDebug)]
/// struct Employee {
/// name: String,
/// #[safe(true)]
/// position: Position,
/// }
///
/// #[derive(SafeDebug)]
/// #[safe(true)]
/// struct Position {
/// id: i32,
/// title: String,
/// #[safe(false)]
/// salary: Range<i32>,
/// }
///
/// let employee = Employee {
/// name: "Kelly Smith".to_string(),
/// position: Position {
/// id: 12,
/// title: "Staff Engineer".to_string(),
/// salary: 200_000..250_000,
/// },
/// };
/// if cfg!(feature = "debug") {
/// assert_eq!(format!("{employee:?}"), r#"Employee { name: "Kelly Smith", position: Position { id: 12, title: "Staff Engineer", salary: 200000..250000 } }"#);
/// } else {
/// assert_eq!(format!("{employee:?}"), r#"Employee { position: Position { id: 12, title: "Staff Engineer", .. }, .. }"#);
/// }
/// ```