1use regex::Regex;
2
3pub use private::Never;
4mod private {
5 use std::process::{ExitCode, Termination};
6 pub struct Never(());
9 impl Termination for Never {
10 fn report(self) -> ExitCode {
11 ExitCode::FAILURE
12 }
13 }
14}
15
16pub trait ToError<E> {
17 fn to_error(self) -> E;
18}
19
20impl<E> ToError<E> for Result<Never, E> {
21 fn to_error(self) -> E {
22 match self {
23 Ok(_) => unsafe { std::hint::unreachable_unchecked() },
24 Err(e) => e,
25 }
26 }
27}
28
29#[macro_export]
30macro_rules! newtype {
31 (
32 $(#[$outer:meta])*
33 $viz:vis $Name:ident $(<$($G:ident),+>)? ($iviz:vis $Inner:ty)
34 ) => {
35 $(#[$outer])*
36 $viz struct $Name $(<$($G),+>)? ($iviz $Inner);
37 impl$(<$($G),+>)? $Name$(<$($G),+>)? {
38 pub fn new(inner: $Inner) -> Self {
39 Self(inner)
40 }
41 }
42 impl $(<$($G),+>)? std::ops::Deref for $Name $(<$($G),+>)? {
43 type Target = $Inner;
44 fn deref(&self) -> &Self::Target {
45 &self.0
46 }
47 }
48 };
49 (
50 $(#[$outer:meta])*
51 $viz:vis mut $Name:ident $(<$($G:ident),+>)? ($iviz:vis $Inner:ty)
52 ) => {
53 $crate::newtype!($(#[$outer])*$viz $Name $(<$($G),+>)? ($iviz $Inner));
54 impl$(<$($G),+>)? std::ops::DerefMut for $Name $(<$($G),+>)? {
55 fn deref_mut(&mut self) -> &mut Self::Target {
56 &mut self.0
57 }
58 }
59 };
60}
61
62#[macro_export]
64macro_rules! clone_to_async {
65 (
66 ($($to_move:ident $(= $orig_name:expr)?),*)
67 |$(mut $arg:ident),*|
68 $blk:expr
69 ) => {{
70 $(
71 $(let $to_move = $orig_name.clone();)?
72 let $to_move = $to_move.clone();
73 )*
74 move |$(mut $arg),*| {
75 $(let $to_move = $to_move.clone();)*
76 async move { $blk }
77 }
78 }};
79 (
80 ($($to_move:ident $(= $orig_name:expr)?),*)
81 |$($arg:ident),*|
82 $blk:expr
83 ) => {{
84 $(
85 $(let $to_move = $orig_name.clone();)?
86 let $to_move = $to_move.clone();
87 )*
88 move |$($arg),*| {
89 $(let $to_move = $to_move.clone();)*
90 async move { $blk }
91 }
92 }};
93}
94
95pub fn short_name<T: ?Sized>() -> String {
96 abs_to_rel_paths(std::any::type_name::<T>())
97}
98
99fn abs_to_rel_paths(s: &str) -> String {
100 let re = Regex::new("[_a-zA-Z0-9]*::").unwrap();
101 re.replace_all(s, "").into()
102}
103
104#[test]
105fn abs_to_rel_paths_works() {
106 assert_eq!(
107 "GenericStruct<UserConfig, Getter<UserConfig>, UserConfigIndex, UserId>",
108 abs_to_rel_paths("some::path::to::GenericStruct<whatever::state::config::UserConfig, my_crate::state::generic::getter::Getter<whatever::state::config::UserConfig>, my_crate::state::caches::UserConfigIndex, lib::user::UserId>")
109 );
110 assert_eq!(
111 "GenericStruct<Repository, RepositoryProvider, Metadata, UserId>",
112 abs_to_rel_paths("some::path::to::GenericStruct<jwt::state::Repository, my_crate::state::account_providers::mint::RepositoryProvider, my_crate::state::generic::meta::Metadata, lib::user::UserId>",)
113 );
114 assert_eq!(
115 "GenericStruct<Market, Getter<Market>, MarketIndex, UserId>",
116 abs_to_rel_paths("some::path::to::GenericStruct<the_app::control::state::Market, my_crate::state::generic::getter::Getter<the_app::control::state::Market>, my_crate::state::caches::MarketIndex, lib::user::UserId>",)
117 );
118 assert_eq!(
119 "GenericStruct<UserItem, UserItemProvider, Metadata, UserId>",
120 abs_to_rel_paths("some::path::to::GenericStruct<whatever_crate::state::UserItem, my_crate::state::account_providers::manager_crate::UserItemProvider, my_crate::state::generic::meta::Metadata, lib::user::UserId>",)
121 );
122 assert_eq!(
123 "GenericStruct<UserAccount, Getter<UserAccount>, Metadata, UserId>",
124 abs_to_rel_paths("some::path::to::GenericStruct<whatever::state::account::UserAccount, my_crate::state::generic::getter::Getter<whatever::state::account::UserAccount>, my_crate::state::generic::meta::Metadata, lib::user::UserId>",)
125 );
126 assert_eq!(
127 "GenericStruct<User, Arc<dyn HttpClient>, UserIndex, UserId>",
128 abs_to_rel_paths("some::path::to::GenericStruct<the_app::manager::state::User, alloc::sync::Arc<dyn clients::http::HttpClient>, my_crate::state::caches::UserIndex, lib::user::UserId>",)
129 );
130 assert_eq!(
131 "GenericStruct<BTreeSet<Entry>, PurchaseProvider, Metadata, UserId>",
132 abs_to_rel_paths("some::path::to::GenericStruct<alloc::collections::btree::set::BTreeSet<my_crate::state::Entry>, my_crate::state::account_providers::thing::PurchaseProvider, my_crate::state::generic::meta::Metadata, lib::user::UserId>",)
133 );
134 assert_eq!(
135 "GenericStruct<ExtSvc, ExtProvider, Metadata, UserId>",
136 abs_to_rel_paths("some::path::to::GenericStruct<ext_sdk::ExtSvc, my_crate::state::account_providers::oracle::ExtProvider, my_crate::state::generic::meta::Metadata, lib::user::UserId>",)
137 );
138 assert_eq!(
139 "GenericStruct<MyItem, UserItemProvider, Metadata, (UserId, UserId)>",
140 abs_to_rel_paths("some::path::to::GenericStruct<whatever_sdk::access::jwt_access::MyItem, my_crate::state::account_providers::access::UserItemProvider, my_crate::state::generic::meta::Metadata, (lib::user::UserId, lib::user::UserId)>",)
141 );
142 assert_eq!(
143 "InstantiatableProvider",
144 abs_to_rel_paths("my_crate::service::provider::InstantiatableProvider"),
145 );
146 assert_eq!(
147 "StaleProvider",
148 abs_to_rel_paths("my_crate::service::provider::StaleProvider"),
149 );
150 assert_eq!(
151 "InstantiationService",
152 abs_to_rel_paths("my_crate::service::dispatch::InstantiationService"),
153 );
154 assert_eq!("DataSync", abs_to_rel_paths("my_crate::init::DataSync"),);
155}