@@ -5,8 +5,8 @@ use std::fmt::{Debug, Display};
55use std:: ops:: Deref ;
66use std:: sync:: LazyLock ;
77
8- enum MaybeLazyInner < T : ' static + ToOwned + ?Sized > {
9- Lazy ( LazyLock < T :: Owned > ) ,
8+ enum MaybeLazyInner < T : ' static + ToOwned + ?Sized , F > {
9+ Lazy ( LazyLock < T :: Owned , F > ) ,
1010 Cow ( Cow < ' static , T > ) ,
1111}
1212
@@ -16,16 +16,16 @@ enum MaybeLazyInner<T: 'static + ToOwned + ?Sized> {
1616/// They can all be constructed from the [`MaybeLazy::borrowed`], [`MaybeLazy::owned`] and
1717/// [`MaybeLazy::lazy`] methods.
1818#[ repr( transparent) ]
19- pub struct MaybeLazy < T : ' static + ToOwned + ?Sized > {
19+ pub struct MaybeLazy < T : ' static + ToOwned + ?Sized , F = fn ( ) -> < T as ToOwned > :: Owned > {
2020 // Inner state.
2121 //
2222 // Not to be inlined since we may want in the future to
2323 // make this struct usable to statics and we might need to
2424 // workaround const-eval limitation (particulary around drop).
25- inner : MaybeLazyInner < T > ,
25+ inner : MaybeLazyInner < T , F > ,
2626}
2727
28- impl < T : ' static + ?Sized + ToOwned > MaybeLazy < T > {
28+ impl < T : ' static + ?Sized + ToOwned , F : FnOnce ( ) -> T :: Owned > MaybeLazy < T , F > {
2929 /// Create a [`MaybeLazy`] from an borrowed `T`.
3030 #[ inline]
3131 pub const fn borrowed ( a : & ' static T ) -> Self {
@@ -38,17 +38,24 @@ impl<T: 'static + ?Sized + ToOwned> MaybeLazy<T> {
3838 MaybeLazy { inner : MaybeLazyInner :: Cow ( Cow :: Owned ( a) ) }
3939 }
4040
41- /// Create a [`MaybeLazy`] that is lazy by taking a function pointer.
42- ///
43- /// This function pointer cannot *ever* take a closure. User can potentially
44- /// workaround that by using closure-to-fnptr or `const` items.
41+ /// Create a [`MaybeLazy`] from a function-able `F`.
42+ #[ inline]
43+ pub const fn lazied ( f : F ) -> Self {
44+ MaybeLazy { inner : MaybeLazyInner :: Lazy ( LazyLock :: new ( f) ) }
45+ }
46+ }
47+
48+ impl < T : ' static + ?Sized + ToOwned > MaybeLazy < T > {
49+ /// Create a [`MaybeLazy`] from a function pointer.
4550 #[ inline]
4651 pub const fn lazy ( a : fn ( ) -> T :: Owned ) -> Self {
4752 MaybeLazy { inner : MaybeLazyInner :: Lazy ( LazyLock :: new ( a) ) }
4853 }
4954}
5055
51- impl < T : ' static + ?Sized + ToOwned < Owned : Clone > > Clone for MaybeLazy < T > {
56+ impl < T : ' static + ?Sized + ToOwned < Owned : Clone > , F : FnOnce ( ) -> T :: Owned > Clone
57+ for MaybeLazy < T , F >
58+ {
5259 #[ inline]
5360 fn clone ( & self ) -> Self {
5461 MaybeLazy {
@@ -60,15 +67,19 @@ impl<T: 'static + ?Sized + ToOwned<Owned: Clone>> Clone for MaybeLazy<T> {
6067 }
6168}
6269
63- impl < T : ' static + ?Sized + ToOwned < Owned : Default > > Default for MaybeLazy < T > {
70+ impl < T : ' static + ?Sized + ToOwned < Owned : Default > , F : FnOnce ( ) -> T :: Owned > Default
71+ for MaybeLazy < T , F >
72+ {
6473 #[ inline]
65- fn default ( ) -> MaybeLazy < T > {
66- MaybeLazy :: lazy ( T :: Owned :: default)
74+ fn default ( ) -> MaybeLazy < T , F > {
75+ MaybeLazy :: owned ( T :: Owned :: default ( ) )
6776 }
6877}
6978
7079// `Debug`, `Display` and other traits below are implemented in terms of this `Deref`
71- impl < T : ' static + ?Sized + ToOwned < Owned : Borrow < T > > > Deref for MaybeLazy < T > {
80+ impl < T : ' static + ?Sized + ToOwned < Owned : Borrow < T > > , F : FnOnce ( ) -> T :: Owned > Deref
81+ for MaybeLazy < T , F >
82+ {
7283 type Target = T ;
7384
7485 #[ inline]
@@ -80,46 +91,54 @@ impl<T: 'static + ?Sized + ToOwned<Owned: Borrow<T>>> Deref for MaybeLazy<T> {
8091 }
8192}
8293
83- impl < T : ' static + ?Sized + ToOwned < Owned : Debug > + Debug > Debug for MaybeLazy < T > {
94+ impl < T : ' static + ?Sized + ToOwned < Owned : Debug > + Debug , F : FnOnce ( ) -> T :: Owned > Debug
95+ for MaybeLazy < T , F >
96+ {
8497 #[ inline]
8598 fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
8699 Debug :: fmt ( & * * self , fmt)
87100 }
88101}
89102
90- impl < T : ' static + ?Sized + ToOwned < Owned : Display > + Display > Display for MaybeLazy < T > {
103+ impl < T : ' static + ?Sized + ToOwned < Owned : Display > + Display , F : FnOnce ( ) -> T :: Owned > Display
104+ for MaybeLazy < T , F >
105+ {
91106 #[ inline]
92107 fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
93108 Display :: fmt ( & * * self , fmt)
94109 }
95110}
96111
97- impl < T : ' static + ?Sized + ToOwned > AsRef < T > for MaybeLazy < T > {
112+ impl < T : ' static + ?Sized + ToOwned , F : FnOnce ( ) -> T :: Owned > AsRef < T > for MaybeLazy < T , F > {
98113 #[ inline]
99114 fn as_ref ( & self ) -> & T {
100115 & * * self
101116 }
102117}
103118
104- impl < B : ?Sized + PartialEq < C > + ToOwned , C : ?Sized + ToOwned > PartialEq < MaybeLazy < C > >
105- for MaybeLazy < B >
119+ impl <
120+ B : ?Sized + PartialEq < C > + ToOwned ,
121+ C : ?Sized + ToOwned ,
122+ F1 : FnOnce ( ) -> B :: Owned ,
123+ F2 : FnOnce ( ) -> C :: Owned ,
124+ > PartialEq < MaybeLazy < C , F2 > > for MaybeLazy < B , F1 >
106125{
107126 #[ inline]
108- fn eq ( & self , other : & MaybeLazy < C > ) -> bool {
127+ fn eq ( & self , other : & MaybeLazy < C , F2 > ) -> bool {
109128 PartialEq :: eq ( & * * self , & * * other)
110129 }
111130}
112131
113- impl PartialEq < & str > for MaybeLazy < str > {
132+ impl < F : FnOnce ( ) -> String > PartialEq < & str > for MaybeLazy < str , F > {
114133 #[ inline]
115134 fn eq ( & self , other : & & str ) -> bool {
116135 & * * self == * other
117136 }
118137}
119138
120- impl From < & ' static str > for MaybeLazy < str > {
139+ impl < F : FnOnce ( ) -> String > From < & ' static str > for MaybeLazy < str , F > {
121140 #[ inline]
122- fn from ( s : & ' static str ) -> MaybeLazy < str > {
141+ fn from ( s : & ' static str ) -> MaybeLazy < str , F > {
123142 MaybeLazy :: borrowed ( s)
124143 }
125144}
0 commit comments