Skip to content

Commit 277223d

Browse files
committed
Make Script and ScriptBuf obey sanity rules
The newtype sanity rules (a name I came up with): * Newtypes should have at most one constructor that directly references the inner field. * Newtypes should have at most three accessor methods that directly reference the ineer field: one for owned access, the second for borrowed and the third for mutably borrowed. * All other methods should use the methods above to perform operations on the newtype and not directly access the fields. This commit makes `Script` and `ScriptBuf` obey these except for `reserve` and `reserve_exact` since we don't have `as_mut_vec` method. As a side effect it also adds `const` to `ScriptBuf::from_bytes`.
1 parent e487618 commit 277223d

File tree

3 files changed

+21
-21
lines changed

3 files changed

+21
-21
lines changed

primitives/src/script/borrowed.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use crate::prelude::{Box, ToOwned, Vec};
5454
///
5555
#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]
5656
#[repr(transparent)]
57-
pub struct Script(pub(in crate::script) [u8]);
57+
pub struct Script([u8]);
5858

5959
impl Default for &Script {
6060
#[inline]
@@ -64,7 +64,7 @@ impl Default for &Script {
6464
impl ToOwned for Script {
6565
type Owned = ScriptBuf;
6666

67-
fn to_owned(&self) -> Self::Owned { ScriptBuf(self.0.to_owned()) }
67+
fn to_owned(&self) -> Self::Owned { ScriptBuf::from_bytes(self.to_vec()) }
6868
}
6969

7070
impl Script {
@@ -104,7 +104,7 @@ impl Script {
104104

105105
/// Returns a copy of the script data.
106106
#[inline]
107-
pub fn to_vec(&self) -> Vec<u8> { self.0.to_owned() }
107+
pub fn to_vec(&self) -> Vec<u8> { self.as_bytes().to_owned() }
108108

109109
/// Returns a copy of the script data.
110110
#[inline]
@@ -113,11 +113,11 @@ impl Script {
113113

114114
/// Returns the length in bytes of the script.
115115
#[inline]
116-
pub fn len(&self) -> usize { self.0.len() }
116+
pub fn len(&self) -> usize { self.as_bytes().len() }
117117

118118
/// Returns whether the script is the empty script.
119119
#[inline]
120-
pub fn is_empty(&self) -> bool { self.0.is_empty() }
120+
pub fn is_empty(&self) -> bool { self.as_bytes().is_empty() }
121121

122122
/// Converts a [`Box<Script>`](Box) into a [`ScriptBuf`] without copying or allocating.
123123
#[must_use]
@@ -128,7 +128,7 @@ impl Script {
128128
// Casting a transparent struct wrapping a slice to the slice pointer is sound (same
129129
// layout).
130130
let inner = unsafe { Box::from_raw(rw) };
131-
ScriptBuf(Vec::from(inner))
131+
ScriptBuf::from_bytes(Vec::from(inner))
132132
}
133133
}
134134

@@ -141,7 +141,7 @@ macro_rules! delegate_index {
141141

142142
#[inline]
143143
fn index(&self, index: $type) -> &Self::Output {
144-
Self::from_bytes(&self.0[index])
144+
Self::from_bytes(&self.as_bytes()[index])
145145
}
146146
}
147147
)*

primitives/src/script/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ impl<'a> From<&'a Script> for Cow<'a, Script> {
236236
#[cfg(target_has_atomic = "ptr")]
237237
impl<'a> From<&'a Script> for Arc<Script> {
238238
fn from(value: &'a Script) -> Self {
239-
let rw: *const [u8] = Arc::into_raw(Arc::from(&value.0));
239+
let rw: *const [u8] = Arc::into_raw(Arc::from(value.as_bytes()));
240240
// SAFETY: copied from `std`
241241
// The pointer was just created from an Arc without deallocating
242242
// Casting a slice to a transparent struct wrapping that slice is sound (same
@@ -247,7 +247,7 @@ impl<'a> From<&'a Script> for Arc<Script> {
247247

248248
impl<'a> From<&'a Script> for Rc<Script> {
249249
fn from(value: &'a Script) -> Self {
250-
let rw: *const [u8] = Rc::into_raw(Rc::from(&value.0));
250+
let rw: *const [u8] = Rc::into_raw(Rc::from(value.as_bytes()));
251251
// SAFETY: copied from `std`
252252
// The pointer was just created from an Rc without deallocating
253253
// Casting a slice to a transparent struct wrapping that slice is sound (same
@@ -257,11 +257,11 @@ impl<'a> From<&'a Script> for Rc<Script> {
257257
}
258258

259259
impl From<Vec<u8>> for ScriptBuf {
260-
fn from(v: Vec<u8>) -> Self { ScriptBuf(v) }
260+
fn from(v: Vec<u8>) -> Self { ScriptBuf::from_bytes(v) }
261261
}
262262

263263
impl From<ScriptBuf> for Vec<u8> {
264-
fn from(v: ScriptBuf) -> Self { v.0 }
264+
fn from(v: ScriptBuf) -> Self { v.into_bytes() }
265265
}
266266

267267
impl AsRef<Script> for Script {
@@ -418,11 +418,11 @@ impl fmt::UpperHex for ScriptBuf {
418418
impl Deref for ScriptBuf {
419419
type Target = Script;
420420

421-
fn deref(&self) -> &Self::Target { Script::from_bytes(&self.0) }
421+
fn deref(&self) -> &Self::Target { self.as_script() }
422422
}
423423

424424
impl DerefMut for ScriptBuf {
425-
fn deref_mut(&mut self) -> &mut Self::Target { Script::from_bytes_mut(&mut self.0) }
425+
fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_script() }
426426
}
427427

428428
impl Borrow<Script> for ScriptBuf {

primitives/src/script/owned.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ use crate::prelude::{Box, Vec};
1919
///
2020
/// [deref coercions]: https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-coercion
2121
#[derive(Default, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
22-
pub struct ScriptBuf(pub(in crate::script) Vec<u8>);
22+
pub struct ScriptBuf(Vec<u8>);
2323

2424
impl ScriptBuf {
2525
/// Constructs a new empty script.
2626
#[inline]
27-
pub const fn new() -> Self { ScriptBuf(Vec::new()) }
27+
pub const fn new() -> Self { ScriptBuf::from_bytes(Vec::new()) }
2828

2929
/// Converts byte vector into script.
3030
///
3131
/// This method doesn't (re)allocate.
32-
pub fn from_bytes(bytes: Vec<u8>) -> Self { ScriptBuf(bytes) }
32+
pub const fn from_bytes(bytes: Vec<u8>) -> Self { ScriptBuf(bytes) }
3333

3434
/// Returns a reference to unsized script.
3535
pub fn as_script(&self) -> &Script { Script::from_bytes(&self.0) }
@@ -52,12 +52,12 @@ impl ScriptBuf {
5252
#[inline]
5353
pub fn into_boxed_script(self) -> Box<Script> {
5454
// Copied from PathBuf::into_boxed_path
55-
let rw = Box::into_raw(self.0.into_boxed_slice()) as *mut Script;
55+
let rw = Box::into_raw(self.into_bytes().into_boxed_slice()) as *mut Script;
5656
unsafe { Box::from_raw(rw) }
5757
}
5858

5959
/// Constructs a new empty script with pre-allocated capacity.
60-
pub fn with_capacity(capacity: usize) -> Self { ScriptBuf(Vec::with_capacity(capacity)) }
60+
pub fn with_capacity(capacity: usize) -> Self { ScriptBuf::from_bytes(Vec::with_capacity(capacity)) }
6161

6262
/// Pre-allocates at least `additional_len` bytes if needed.
6363
///
@@ -91,7 +91,7 @@ impl ScriptBuf {
9191
impl<'a> Arbitrary<'a> for ScriptBuf {
9292
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
9393
let v = Vec::<u8>::arbitrary(u)?;
94-
Ok(ScriptBuf(v))
94+
Ok(ScriptBuf::from_bytes(v))
9595
}
9696
}
9797

@@ -103,7 +103,7 @@ mod tests {
103103
fn script_buf_from_bytes() {
104104
let bytes = vec![1, 2, 3];
105105
let script = ScriptBuf::from_bytes(bytes.clone());
106-
assert_eq!(script.0, bytes);
106+
assert_eq!(script.as_bytes(), bytes);
107107
}
108108

109109
#[test]
@@ -120,7 +120,7 @@ mod tests {
120120
let mut script = ScriptBuf::from_bytes(bytes.clone());
121121
let script_mut_ref = script.as_mut_script();
122122
script_mut_ref.as_mut_bytes()[0] = 4;
123-
assert_eq!(script.0, vec![4, 2, 3]);
123+
assert_eq!(script.as_mut_bytes(), vec![4, 2, 3]);
124124
}
125125

126126
#[test]

0 commit comments

Comments
 (0)