1#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
77#![cfg_attr(all(test, feature = "unstable"), feature(test))]
78#![deny(unsafe_code)]
80#![deny(non_upper_case_globals)]
81#![deny(non_camel_case_types)]
82#![deny(non_snake_case)]
83#![deny(unused_mut)]
84#![deny(unused_imports)]
85#![deny(missing_docs)]
86
87#[cfg(target_pointer_width = "16")]
88compile_error!(
89 "rust-miniscript currently only supports architectures with pointers wider than 16 bits"
90);
91
92#[cfg(not(any(feature = "std", feature = "no-std")))]
93compile_error!("at least one of the `std` or `no-std` features must be enabled");
94
95pub use bellscoin;
96
97#[cfg(not(feature = "std"))]
98#[macro_use]
99extern crate alloc;
100
101#[cfg(not(feature = "std"))]
102extern crate hashbrown;
103
104#[cfg(any(feature = "std", test))]
105extern crate core;
106
107#[cfg(feature = "serde")]
108pub use actual_serde as serde;
109#[cfg(all(test, feature = "unstable"))]
110extern crate test;
111
112#[macro_use]
113mod macros;
114
115#[macro_use]
116mod pub_macros;
117
118use internals::hex::exts::DisplayHex;
119
120pub mod descriptor;
121pub mod expression;
122pub mod interpreter;
123pub mod miniscript;
124pub mod policy;
125pub mod psbt;
126
127#[cfg(test)]
128mod test_utils;
129mod util;
130
131use core::{cmp, fmt, hash, str};
132#[cfg(feature = "std")]
133use std::error;
134
135use bellscoin::blockdata::{opcodes, script};
136use bellscoin::hashes::{hash160, ripemd160, sha256, Hash};
137use bellscoin::locktime::absolute;
138
139pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey};
140pub use crate::interpreter::Interpreter;
141pub use crate::miniscript::analyzable::{AnalysisError, ExtParams};
142pub use crate::miniscript::context::{BareCtx, Legacy, ScriptContext, Segwitv0, SigType, Tap};
143pub use crate::miniscript::decode::Terminal;
144pub use crate::miniscript::satisfy::{Preimage32, Satisfier};
145pub use crate::miniscript::{hash256, Miniscript};
146use crate::prelude::*;
147
148pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Hash {
150 fn is_uncompressed(&self) -> bool {
152 false
153 }
154
155 fn is_x_only_key(&self) -> bool {
159 false
160 }
161
162 fn num_der_paths(&self) -> usize;
165
166 type Sha256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
169
170 type Hash256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
173
174 type Ripemd160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
177
178 type Hash160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
181}
182
183impl MiniscriptKey for bellscoin::secp256k1::PublicKey {
184 type Sha256 = sha256::Hash;
185 type Hash256 = hash256::Hash;
186 type Ripemd160 = ripemd160::Hash;
187 type Hash160 = hash160::Hash;
188
189 fn num_der_paths(&self) -> usize {
190 0
191 }
192}
193
194impl MiniscriptKey for bellscoin::PublicKey {
195 fn is_uncompressed(&self) -> bool {
197 !self.compressed
198 }
199
200 fn num_der_paths(&self) -> usize {
201 0
202 }
203
204 type Sha256 = sha256::Hash;
205 type Hash256 = hash256::Hash;
206 type Ripemd160 = ripemd160::Hash;
207 type Hash160 = hash160::Hash;
208}
209
210impl MiniscriptKey for bellscoin::secp256k1::XOnlyPublicKey {
211 type Sha256 = sha256::Hash;
212 type Hash256 = hash256::Hash;
213 type Ripemd160 = ripemd160::Hash;
214 type Hash160 = hash160::Hash;
215
216 fn is_x_only_key(&self) -> bool {
217 true
218 }
219
220 fn num_der_paths(&self) -> usize {
221 0
222 }
223}
224
225impl MiniscriptKey for String {
226 type Sha256 = String; type Hash256 = String;
228 type Ripemd160 = String;
229 type Hash160 = String;
230
231 fn num_der_paths(&self) -> usize {
232 0
233 }
234}
235
236pub trait ToPublicKey: MiniscriptKey {
238 fn to_public_key(&self) -> bellscoin::PublicKey;
240
241 fn to_x_only_pubkey(&self) -> bellscoin::secp256k1::XOnlyPublicKey {
243 let pk = self.to_public_key();
244 bellscoin::secp256k1::XOnlyPublicKey::from(pk.inner)
245 }
246
247 fn to_pubkeyhash(&self, sig_type: SigType) -> hash160::Hash {
252 match sig_type {
253 SigType::Ecdsa => hash160::Hash::hash(&self.to_public_key().to_bytes()),
254 SigType::Schnorr => hash160::Hash::hash(&self.to_x_only_pubkey().serialize()),
255 }
256 }
257
258 fn to_sha256(hash: &<Self as MiniscriptKey>::Sha256) -> sha256::Hash;
260
261 fn to_hash256(hash: &<Self as MiniscriptKey>::Hash256) -> hash256::Hash;
263
264 fn to_ripemd160(hash: &<Self as MiniscriptKey>::Ripemd160) -> ripemd160::Hash;
266
267 fn to_hash160(hash: &<Self as MiniscriptKey>::Hash160) -> hash160::Hash;
269}
270
271impl ToPublicKey for bellscoin::PublicKey {
272 fn to_public_key(&self) -> bellscoin::PublicKey {
273 *self
274 }
275
276 fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {
277 *hash
278 }
279
280 fn to_hash256(hash: &hash256::Hash) -> hash256::Hash {
281 *hash
282 }
283
284 fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash {
285 *hash
286 }
287
288 fn to_hash160(hash: &hash160::Hash) -> hash160::Hash {
289 *hash
290 }
291}
292
293impl ToPublicKey for bellscoin::secp256k1::PublicKey {
294 fn to_public_key(&self) -> bellscoin::PublicKey {
295 bellscoin::PublicKey::new(*self)
296 }
297
298 fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {
299 *hash
300 }
301
302 fn to_hash256(hash: &hash256::Hash) -> hash256::Hash {
303 *hash
304 }
305
306 fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash {
307 *hash
308 }
309
310 fn to_hash160(hash: &hash160::Hash) -> hash160::Hash {
311 *hash
312 }
313}
314
315impl ToPublicKey for bellscoin::secp256k1::XOnlyPublicKey {
316 fn to_public_key(&self) -> bellscoin::PublicKey {
317 let mut data: Vec<u8> = vec![0x02];
320 data.extend(self.serialize().iter());
321 bellscoin::PublicKey::from_slice(&data)
322 .expect("Failed to construct 33 Publickey from 0x02 appended x-only key")
323 }
324
325 fn to_x_only_pubkey(&self) -> bellscoin::secp256k1::XOnlyPublicKey {
326 *self
327 }
328
329 fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {
330 *hash
331 }
332
333 fn to_hash256(hash: &hash256::Hash) -> hash256::Hash {
334 *hash
335 }
336
337 fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash {
338 *hash
339 }
340
341 fn to_hash160(hash: &hash160::Hash) -> hash160::Hash {
342 *hash
343 }
344}
345
346pub trait Translator<P, Q, E>
349where
350 P: MiniscriptKey,
351 Q: MiniscriptKey,
352{
353 fn pk(&mut self, pk: &P) -> Result<Q, E>;
355
356 fn sha256(&mut self, sha256: &P::Sha256) -> Result<Q::Sha256, E>;
358
359 fn hash256(&mut self, hash256: &P::Hash256) -> Result<Q::Hash256, E>;
361
362 fn ripemd160(&mut self, ripemd160: &P::Ripemd160) -> Result<Q::Ripemd160, E>;
364
365 fn hash160(&mut self, hash160: &P::Hash160) -> Result<Q::Hash160, E>;
367}
368
369pub enum TranslateErr<E> {
371 TranslatorErr(E),
373 OuterError(Error),
377}
378
379impl<E> TranslateErr<E> {
380 pub fn expect_translator_err(self, msg: &str) -> E {
396 if let Self::TranslatorErr(v) = self {
397 v
398 } else {
399 panic!("{}", msg)
400 }
401 }
402}
403
404impl<E> From<E> for TranslateErr<E> {
405 fn from(v: E) -> Self {
406 Self::TranslatorErr(v)
407 }
408}
409
410impl<E: fmt::Debug> fmt::Debug for TranslateErr<E> {
412 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
413 match self {
414 Self::TranslatorErr(e) => write!(f, "TranslatorErr({:?})", e),
415 Self::OuterError(e) => write!(f, "OuterError({:?})", e),
416 }
417 }
418}
419
420pub trait TranslatePk<P, Q>
423where
424 P: MiniscriptKey,
425 Q: MiniscriptKey,
426{
427 type Output;
429
430 fn translate_pk<T, E>(&self, translator: &mut T) -> Result<Self::Output, TranslateErr<E>>
433 where
434 T: Translator<P, Q, E>;
435}
436
437pub trait ForEachKey<Pk: MiniscriptKey> {
449 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
452 where
453 Pk: 'a;
454
455 fn for_any_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
458 where
459 Pk: 'a,
460 {
461 !self.for_each_key(|key| !pred(key))
462 }
463}
464
465#[derive(Debug, PartialEq)]
468pub enum Error {
469 InvalidOpcode(opcodes::All),
471 NonMinimalVerify(String),
474 InvalidPush(Vec<u8>),
476 Script(script::Error),
478 AddrError(bellscoin::address::Error),
480 CmsTooManyKeys(u32),
482 MultiATooManyKeys(u32),
484 Unprintable(u8),
486 ExpectedChar(char),
488 UnexpectedStart,
490 Unexpected(String),
492 MultiColon(String),
494 MultiAt(String),
496 AtOutsideOr(String),
498 LikelyFalse,
500 UnknownWrapper(char),
502 NonTopLevel(String),
504 Trailing(String),
506 BadPubkey(bellscoin::key::Error),
508 MissingHash(sha256::Hash),
510 MissingSig(bellscoin::PublicKey),
512 RelativeLocktimeNotMet(u32),
514 AbsoluteLocktimeNotMet(u32),
516 CouldNotSatisfy,
518 TypeCheck(String),
520 BadDescriptor(String),
522 Secp(bellscoin::secp256k1::Error),
524 #[cfg(feature = "compiler")]
525 CompilerError(crate::policy::compiler::CompilerError),
527 PolicyError(policy::concrete::PolicyError),
529 LiftError(policy::LiftError),
531 ContextError(miniscript::context::ScriptContextError),
533 MaxRecursiveDepthExceeded,
535 ScriptSizeTooLarge,
537 NonStandardBareScript,
540 AnalysisError(miniscript::analyzable::AnalysisError),
542 ImpossibleSatisfaction,
544 BareDescriptorAddr,
546 PubKeyCtxError(miniscript::decode::KeyParseError, &'static str),
548 TaprootSpendInfoUnavialable,
550 TrNoScriptCode,
552 TrNoExplicitScript,
554 MultipathDescLenMismatch,
557}
558
559const MAX_RECURSION_DEPTH: u32 = 402;
561const MAX_SCRIPT_SIZE: u32 = 10000;
563
564impl fmt::Display for Error {
565 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
566 match *self {
567 Error::InvalidOpcode(op) => write!(f, "invalid opcode {}", op),
568 Error::NonMinimalVerify(ref tok) => write!(f, "{} VERIFY", tok),
569 Error::InvalidPush(ref push) => {
570 write!(f, "invalid push {:x}", push.as_hex())
571 },
572 Error::Script(ref e) => fmt::Display::fmt(e, f),
573 Error::AddrError(ref e) => fmt::Display::fmt(e, f),
574 Error::CmsTooManyKeys(n) => write!(f, "checkmultisig with {} keys", n),
575 Error::Unprintable(x) => write!(f, "unprintable character 0x{:02x}", x),
576 Error::ExpectedChar(c) => write!(f, "expected {}", c),
577 Error::UnexpectedStart => f.write_str("unexpected start of script"),
578 Error::Unexpected(ref s) => write!(f, "unexpected «{}»", s),
579 Error::MultiColon(ref s) => write!(f, "«{}» has multiple instances of «:»", s),
580 Error::MultiAt(ref s) => write!(f, "«{}» has multiple instances of «@»", s),
581 Error::AtOutsideOr(ref s) => write!(f, "«{}» contains «@» in non-or() context", s),
582 Error::LikelyFalse => write!(f, "0 is not very likely (use «u:0»)"),
583 Error::UnknownWrapper(ch) => write!(f, "unknown wrapper «{}:»", ch),
584 Error::NonTopLevel(ref s) => write!(f, "non-T miniscript: {}", s),
585 Error::Trailing(ref s) => write!(f, "trailing tokens: {}", s),
586 Error::MissingHash(ref h) => write!(f, "missing preimage of hash {}", h),
587 Error::MissingSig(ref pk) => write!(f, "missing signature for key {:?}", pk),
588 Error::RelativeLocktimeNotMet(n) => {
589 write!(f, "required relative locktime CSV of {} blocks, not met", n)
590 }
591 Error::AbsoluteLocktimeNotMet(n) => write!(
592 f,
593 "required absolute locktime CLTV of {} blocks, not met",
594 n
595 ),
596 Error::CouldNotSatisfy => f.write_str("could not satisfy"),
597 Error::BadPubkey(ref e) => fmt::Display::fmt(e, f),
598 Error::TypeCheck(ref e) => write!(f, "typecheck: {}", e),
599 Error::BadDescriptor(ref e) => write!(f, "Invalid descriptor: {}", e),
600 Error::Secp(ref e) => fmt::Display::fmt(e, f),
601 Error::ContextError(ref e) => fmt::Display::fmt(e, f),
602 #[cfg(feature = "compiler")]
603 Error::CompilerError(ref e) => fmt::Display::fmt(e, f),
604 Error::PolicyError(ref e) => fmt::Display::fmt(e, f),
605 Error::LiftError(ref e) => fmt::Display::fmt(e, f),
606 Error::MaxRecursiveDepthExceeded => write!(
607 f,
608 "Recursive depth over {} not permitted",
609 MAX_RECURSION_DEPTH
610 ),
611 Error::ScriptSizeTooLarge => write!(
612 f,
613 "Standardness rules imply bitcoin than {} bytes",
614 MAX_SCRIPT_SIZE
615 ),
616 Error::NonStandardBareScript => write!(
617 f,
618 "Anything but c:pk(key) (P2PK), c:pk_h(key) (P2PKH), and thresh_m(k,...) \
619 up to n=3 is invalid by standardness (bare).
620 "
621 ),
622 Error::AnalysisError(ref e) => e.fmt(f),
623 Error::ImpossibleSatisfaction => write!(f, "Impossible to satisfy Miniscript"),
624 Error::BareDescriptorAddr => write!(f, "Bare descriptors don't have address"),
625 Error::PubKeyCtxError(ref pk, ref ctx) => {
626 write!(f, "Pubkey error: {} under {} scriptcontext", pk, ctx)
627 }
628 Error::MultiATooManyKeys(k) => write!(f, "MultiA too many keys {}", k),
629 Error::TaprootSpendInfoUnavialable => write!(f, "Taproot Spend Info not computed."),
630 Error::TrNoScriptCode => write!(f, "No script code for Tr descriptors"),
631 Error::TrNoExplicitScript => write!(f, "No script code for Tr descriptors"),
632 Error::MultipathDescLenMismatch => write!(f, "At least two BIP389 key expressions in the descriptor contain tuples of derivation indexes of different lengths"),
633 }
634 }
635}
636
637#[cfg(feature = "std")]
638impl error::Error for Error {
639 fn cause(&self) -> Option<&dyn error::Error> {
640 use self::Error::*;
641
642 match self {
643 InvalidOpcode(_)
644 | NonMinimalVerify(_)
645 | InvalidPush(_)
646 | CmsTooManyKeys(_)
647 | MultiATooManyKeys(_)
648 | Unprintable(_)
649 | ExpectedChar(_)
650 | UnexpectedStart
651 | Unexpected(_)
652 | MultiColon(_)
653 | MultiAt(_)
654 | AtOutsideOr(_)
655 | LikelyFalse
656 | UnknownWrapper(_)
657 | NonTopLevel(_)
658 | Trailing(_)
659 | MissingHash(_)
660 | MissingSig(_)
661 | RelativeLocktimeNotMet(_)
662 | AbsoluteLocktimeNotMet(_)
663 | CouldNotSatisfy
664 | TypeCheck(_)
665 | BadDescriptor(_)
666 | MaxRecursiveDepthExceeded
667 | ScriptSizeTooLarge
668 | NonStandardBareScript
669 | ImpossibleSatisfaction
670 | BareDescriptorAddr
671 | TaprootSpendInfoUnavialable
672 | TrNoScriptCode
673 | TrNoExplicitScript
674 | MultipathDescLenMismatch => None,
675 Script(e) => Some(e),
676 AddrError(e) => Some(e),
677 BadPubkey(e) => Some(e),
678 Secp(e) => Some(e),
679 #[cfg(feature = "compiler")]
680 CompilerError(e) => Some(e),
681 PolicyError(e) => Some(e),
682 LiftError(e) => Some(e),
683 ContextError(e) => Some(e),
684 AnalysisError(e) => Some(e),
685 PubKeyCtxError(e, _) => Some(e),
686 }
687 }
688}
689
690#[doc(hidden)]
691impl<Pk, Ctx> From<miniscript::types::Error<Pk, Ctx>> for Error
692where
693 Pk: MiniscriptKey,
694 Ctx: ScriptContext,
695{
696 fn from(e: miniscript::types::Error<Pk, Ctx>) -> Error {
697 Error::TypeCheck(e.to_string())
698 }
699}
700
701#[doc(hidden)]
702impl From<policy::LiftError> for Error {
703 fn from(e: policy::LiftError) -> Error {
704 Error::LiftError(e)
705 }
706}
707
708#[doc(hidden)]
709impl From<miniscript::context::ScriptContextError> for Error {
710 fn from(e: miniscript::context::ScriptContextError) -> Error {
711 Error::ContextError(e)
712 }
713}
714
715#[doc(hidden)]
716impl From<miniscript::analyzable::AnalysisError> for Error {
717 fn from(e: miniscript::analyzable::AnalysisError) -> Error {
718 Error::AnalysisError(e)
719 }
720}
721
722#[doc(hidden)]
723impl From<bellscoin::secp256k1::Error> for Error {
724 fn from(e: bellscoin::secp256k1::Error) -> Error {
725 Error::Secp(e)
726 }
727}
728
729#[doc(hidden)]
730impl From<bellscoin::address::Error> for Error {
731 fn from(e: bellscoin::address::Error) -> Error {
732 Error::AddrError(e)
733 }
734}
735
736#[doc(hidden)]
737#[cfg(feature = "compiler")]
738impl From<crate::policy::compiler::CompilerError> for Error {
739 fn from(e: crate::policy::compiler::CompilerError) -> Error {
740 Error::CompilerError(e)
741 }
742}
743
744#[doc(hidden)]
745impl From<policy::concrete::PolicyError> for Error {
746 fn from(e: policy::concrete::PolicyError) -> Error {
747 Error::PolicyError(e)
748 }
749}
750
751fn errstr(s: &str) -> Error {
752 Error::Unexpected(s.to_owned())
753}
754
755pub fn script_num_size(n: usize) -> usize {
757 match n {
758 n if n <= 0x10 => 1, n if n < 0x80 => 2, n if n < 0x8000 => 3, n if n < 0x800000 => 4, n if n < 0x80000000 => 5, _ => 6, }
765}
766
767fn push_opcode_size(script_size: usize) -> usize {
773 if script_size < 76 {
774 1
775 } else if script_size < 0x100 {
776 2
777 } else if script_size < 0x10000 {
778 3
779 } else {
780 5
781 }
782}
783
784#[cfg(test)]
786fn hex_script(s: &str) -> bellscoin::ScriptBuf {
787 let v: Vec<u8> = bellscoin::hashes::hex::FromHex::from_hex(s).unwrap();
788 bellscoin::ScriptBuf::from(v)
789}
790
791#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
793pub struct AbsLockTime(absolute::LockTime);
794
795impl AbsLockTime {
796 pub fn from_consensus(n: u32) -> Self {
798 Self(absolute::LockTime::from_consensus(n))
799 }
800
801 pub fn to_consensus_u32(self) -> u32 {
807 self.0.to_consensus_u32()
808 }
809
810 pub fn to_u32(self) -> u32 {
814 self.to_consensus_u32()
815 }
816}
817
818impl From<absolute::LockTime> for AbsLockTime {
819 fn from(lock_time: absolute::LockTime) -> Self {
820 Self(lock_time)
821 }
822}
823
824impl From<AbsLockTime> for absolute::LockTime {
825 fn from(lock_time: AbsLockTime) -> absolute::LockTime {
826 lock_time.0
827 }
828}
829
830impl cmp::PartialOrd for AbsLockTime {
831 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
832 Some(self.cmp(other))
833 }
834}
835
836impl cmp::Ord for AbsLockTime {
837 fn cmp(&self, other: &Self) -> cmp::Ordering {
838 let this = self.0.to_consensus_u32();
839 let that = other.0.to_consensus_u32();
840 this.cmp(&that)
841 }
842}
843
844impl fmt::Display for AbsLockTime {
845 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
846 fmt::Display::fmt(&self.0, f)
847 }
848}
849
850#[cfg(test)]
851mod tests {
852 use core::str::FromStr;
853
854 use super::*;
855
856 #[test]
857 fn regression_bitcoin_key_hash() {
858 use bellscoin::PublicKey;
859
860 let pk = PublicKey::from_str(
862 "042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133"
863 ).unwrap();
864
865 let want = hash160::Hash::from_str("ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a").unwrap();
866 let got = pk.to_pubkeyhash(SigType::Ecdsa);
867 assert_eq!(got, want)
868 }
869
870 #[test]
871 fn regression_secp256k1_key_hash() {
872 use bellscoin::secp256k1::PublicKey;
873
874 let pk = PublicKey::from_str(
876 "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
877 )
878 .unwrap();
879
880 let want = hash160::Hash::from_str("9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4").unwrap();
881 let got = pk.to_pubkeyhash(SigType::Ecdsa);
882 assert_eq!(got, want)
883 }
884
885 #[test]
886 fn regression_xonly_key_hash() {
887 use bellscoin::secp256k1::XOnlyPublicKey;
888
889 let pk = XOnlyPublicKey::from_str(
890 "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115",
891 )
892 .unwrap();
893
894 let want = hash160::Hash::from_str("eb8ac65f971ae688a94aeabf223506865e7e08f2").unwrap();
895 let got = pk.to_pubkeyhash(SigType::Schnorr);
896 assert_eq!(got, want)
897 }
898}
899
900#[allow(unused_imports)] mod prelude {
902 #[cfg(all(not(feature = "std"), not(test)))]
905 mod mutex {
906 use core::cell::{RefCell, RefMut};
907 use core::ops::{Deref, DerefMut};
908
909 pub type LockResult<Guard> = Result<Guard, ()>;
910
911 pub struct Mutex<T: ?Sized> {
915 inner: RefCell<T>,
916 }
917
918 #[must_use = "if unused the Mutex will immediately unlock"]
919 pub struct MutexGuard<'a, T: ?Sized + 'a> {
920 lock: RefMut<'a, T>,
921 }
922
923 impl<T: ?Sized> Deref for MutexGuard<'_, T> {
924 type Target = T;
925
926 fn deref(&self) -> &T {
927 &self.lock.deref()
928 }
929 }
930
931 impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
932 fn deref_mut(&mut self) -> &mut T {
933 self.lock.deref_mut()
934 }
935 }
936
937 impl<T> Mutex<T> {
938 pub fn new(inner: T) -> Mutex<T> {
939 Mutex {
940 inner: RefCell::new(inner),
941 }
942 }
943
944 pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
945 Ok(MutexGuard {
946 lock: self.inner.borrow_mut(),
947 })
948 }
949 }
950 }
951
952 #[cfg(all(not(feature = "std"), not(test)))]
953 pub use alloc::{
954 borrow::{Borrow, Cow, ToOwned},
955 boxed::Box,
956 collections::{vec_deque::VecDeque, BTreeMap, BTreeSet, BinaryHeap},
957 rc, slice,
958 string::{String, ToString},
959 sync,
960 vec::Vec,
961 };
962 #[cfg(any(feature = "std", test))]
963 pub use std::{
964 borrow::{Borrow, ToOwned},
965 boxed::Box,
966 collections::{vec_deque::VecDeque, BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet},
967 string::{String, ToString},
968 sync,
969 sync::Mutex,
970 vec::Vec,
971 };
972
973 #[cfg(all(not(feature = "std"), not(test)))]
974 pub use hashbrown::{HashMap, HashSet};
975
976 #[cfg(all(not(feature = "std"), not(test)))]
977 pub use self::mutex::Mutex;
978}