Skip to main content

bestool_canopy/
lib.rs

1use std::fmt;
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5mod backup;
6mod client;
7pub mod registration;
8
9pub use backup::{
10	BackupCredentials, BackupCredentialsRequest, BackupReport, BackupTarget, CapabilitiesRequest,
11	ContainerCreds, Outcome, Purpose, TargetOutcome,
12};
13pub use client::{
14	CERT_RENEW_AFTER, CanopyClient, ClientBuilderFactory, DEFAULT_CANOPY_URL, NewEvent, Severity,
15	TAILSCALE_URL, client_builder, device_identity, tailscale_client, user_agent,
16};
17
18/// Wraps a sensitive value so its `Debug` output doesn't leak the contents.
19#[derive(Clone)]
20pub struct Redacted<T>(pub T);
21
22impl<T> fmt::Debug for Redacted<T> {
23	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24		f.write_str("<redacted>")
25	}
26}
27
28impl<T> std::ops::Deref for Redacted<T> {
29	type Target = T;
30	fn deref(&self) -> &T {
31		&self.0
32	}
33}
34
35impl<T: Serialize> Serialize for Redacted<T> {
36	fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
37		self.0.serialize(serializer)
38	}
39}
40
41impl<'de, T: Deserialize<'de>> Deserialize<'de> for Redacted<T> {
42	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
43		T::deserialize(deserializer).map(Redacted)
44	}
45}