Skip to content

Commit

Permalink
Change new, try_new to new_or_panic, new
Browse files Browse the repository at this point in the history
  • Loading branch information
yescallop committed Jun 4, 2024
1 parent facdb1e commit 1410d8e
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 73 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ A full-featured URI handling library compliant with [RFC 3986]. It is:

```rust
let uri: Uri<String> = Uri::builder()
.scheme(Scheme::new("foo"))
.scheme(Scheme::new_or_panic("foo"))
.authority(|b| {
b.userinfo(EStr::new("user"))
.host(EStr::new("example.com"))
b.userinfo(EStr::new_or_panic("user"))
.host(EStr::new_or_panic("example.com"))
.port(8042)
})
.path(EStr::new("/over/there"))
.query(EStr::new("name=ferret"))
.fragment(EStr::new("nose"))
.path(EStr::new_or_panic("/over/there"))
.query(EStr::new_or_panic("name=ferret"))
.fragment(EStr::new_or_panic("nose"))
.build();

assert_eq!(
Expand Down Expand Up @@ -79,7 +79,7 @@ A full-featured URI handling library compliant with [RFC 3986]. It is:
let query = "name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21";
let map: HashMap<_, _> = EStr::<Query>::new(query)
.split('&')
.map(|s| s.split_once('=').unwrap_or((s, EStr::new(""))))
.map(|s| s.split_once('=').unwrap_or((s, EStr::EMPTY)))
.map(|(k, v)| (k.decode().into_string_lossy(), v.decode().into_string_lossy()))
.collect();
assert_eq!(map["name"], "张三");
Expand All @@ -105,7 +105,7 @@ A full-featured URI handling library compliant with [RFC 3986]. It is:
assert_eq!(buf, "name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21");

let uri = Uri::builder()
.path(EStr::new(""))
.path(EStr::new_or_panic(""))
.query(&buf)
.build();
assert_eq!(uri.as_str(), "?name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21");
Expand Down
12 changes: 6 additions & 6 deletions bench/benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ fn bench_build(c: &mut Criterion) {
c.bench_function("build", |b| {
b.iter(|| {
Uri::builder()
.scheme(Scheme::new("foo"))
.scheme(Scheme::new_or_panic("foo"))
.authority(|b| {
b.userinfo(EStr::new("user"))
.host(EStr::new("example.com"))
b.userinfo(EStr::new_or_panic("user"))
.host(EStr::new_or_panic("example.com"))
.port(8042)
})
.path(EStr::new("/over/there"))
.query(EStr::new("name=ferret"))
.fragment(EStr::new("nose"))
.path(EStr::new_or_panic("/over/there"))
.query(EStr::new_or_panic("name=ferret"))
.fragment(EStr::new_or_panic("nose"))
.build()
})
});
Expand Down
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/build_parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct SchemeWrapper<'a>(&'a Scheme);

impl<'a> Arbitrary<'a> for SchemeWrapper<'a> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Scheme::try_new(u.arbitrary()?)
Scheme::new(u.arbitrary()?)
.map(SchemeWrapper)
.ok_or(Error::IncorrectFormat)
}
Expand All @@ -42,7 +42,7 @@ impl<'a, E: Encoder> Copy for EStrWrapper<'a, E> {}

impl<'a, E: Encoder> Arbitrary<'a> for EStrWrapper<'a, E> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
EStr::try_new(u.arbitrary()?)
EStr::new(u.arbitrary()?)
.map(EStrWrapper)
.ok_or(Error::IncorrectFormat)
}
Expand Down
28 changes: 14 additions & 14 deletions src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ use state::*;
/// use fluent_uri::{component::Scheme, encoding::EStr, Uri};
///
/// let uri: Uri<String> = Uri::builder()
/// .scheme(Scheme::new("foo"))
/// .scheme(Scheme::new_or_panic("foo"))
/// .authority(|b| {
/// b.userinfo(EStr::new("user"))
/// .host(EStr::new("example.com"))
/// b.userinfo(EStr::new_or_panic("user"))
/// .host(EStr::new_or_panic("example.com"))
/// .port(8042)
/// })
/// .path(EStr::new("/over/there"))
/// .query(EStr::new("name=ferret"))
/// .fragment(EStr::new("nose"))
/// .path(EStr::new_or_panic("/over/there"))
/// .query(EStr::new_or_panic("name=ferret"))
/// .fragment(EStr::new_or_panic("nose"))
/// .build()
/// .unwrap();
///
Expand All @@ -46,7 +46,7 @@ use state::*;
/// );
/// ```
///
/// Note that [`EStr::new`] *panics* on invalid input and should only be used
/// Note that [`EStr::new_or_panic`] *panics* on invalid input and should only be used
/// when you know that the string is properly percent-encoded.
/// If you want to build a percent-encoded string from scratch,
/// use [`EString`] instead.
Expand Down Expand Up @@ -214,10 +214,10 @@ impl<S> Builder<S> {
/// let b = if relative {
/// b.advance()
/// } else {
/// b.scheme(Scheme::new("http"))
/// .authority(|b| b.host(EStr::new("example.com")))
/// b.scheme(Scheme::new_or_panic("http"))
/// .authority(|b| b.host(EStr::new_or_panic("example.com")))
/// };
/// b.path(EStr::new("/foo")).build().unwrap()
/// b.path(EStr::new_or_panic("/foo")).build().unwrap()
/// }
///
/// assert_eq!(build(false).as_str(), "http://example.com/foo");
Expand All @@ -237,8 +237,8 @@ impl<S> Builder<S> {
/// use fluent_uri::{encoding::EStr, Builder, Uri};
///
/// let uri = Uri::builder()
/// .path(EStr::new("foo"))
/// .optional(Builder::query, Some(EStr::new("bar")))
/// .path(EStr::new_or_panic("foo"))
/// .optional(Builder::query, Some(EStr::new_or_panic("bar")))
/// .optional(Builder::fragment, None)
/// .build()
/// .unwrap();
Expand Down Expand Up @@ -324,8 +324,8 @@ impl<S: To<HostEnd>> Builder<S> {
/// use fluent_uri::{component::Host, encoding::EStr, Uri};
///
/// let uri = Uri::builder()
/// .authority(|b| b.host(EStr::new("127.0.0.1")))
/// .path(EStr::new(""))
/// .authority(|b| b.host(EStr::new_or_panic("127.0.0.1")))
/// .path(EStr::EMPTY)
/// .build()
/// .unwrap();
/// assert!(matches!(uri.authority().unwrap().host_parsed(), Host::Ipv4(_)));
Expand Down
14 changes: 6 additions & 8 deletions src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use std::{
/// let scheme = uri.scheme().unwrap();
///
/// // Case-insensitive comparison.
/// assert_eq!(scheme, Scheme::new("http"));
/// assert_eq!(scheme, Scheme::new_or_panic("http"));
/// // Case-sensitive comparison.
/// assert_eq!(scheme.as_str(), "HTTP");
/// # Ok::<_, fluent_uri::error::ParseError>(())
Expand All @@ -61,24 +61,22 @@ impl Scheme {
///
/// Panics if the string is not a valid scheme name according to
/// [Section 3.1 of RFC 3986][scheme]. For a non-panicking variant,
/// use [`try_new`](Self::try_new).
/// use [`new`](Self::new).
///
/// [scheme]: https://datatracker.ietf.org/doc/html/rfc3986/#section-3.1
#[inline]
#[must_use]
pub const fn new(s: &str) -> &Scheme {
match Self::try_new(s) {
pub const fn new_or_panic(s: &str) -> &Scheme {
match Self::new(s) {
Some(scheme) => scheme,
None => panic!("invalid scheme"),
}
}

/// Converts a string slice to `&Scheme`, returning `None` if the conversion fails.
///
/// This is the non-panicking variant of [`new`](Self::new).
#[inline]
#[must_use]
pub const fn try_new(s: &str) -> Option<&Scheme> {
pub const fn new(s: &str) -> Option<&Scheme> {
if matches!(s.as_bytes(), [first, rem @ ..]
if first.is_ascii_alphabetic() && table::SCHEME.validate(rem))
{
Expand Down Expand Up @@ -186,7 +184,7 @@ impl<'i, 'o, T: BorrowOrShare<'i, 'o, str>> Authority<T> {
///
/// let uri = Uri::parse("http://user@example.com/")?;
/// let auth = uri.authority().unwrap();
/// assert_eq!(auth.userinfo(), Some(EStr::new("user")));
/// assert_eq!(auth.userinfo(), Some(EStr::new_or_panic("user")));
///
/// let uri = Uri::parse("http://example.com/")?;
/// let auth = uri.authority().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion src/encoding/estring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use core::{borrow::Borrow, cmp::Ordering, hash, marker::PhantomData, ops::Deref}
/// assert_eq!(buf, "name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21");
///
/// let uri = Uri::builder()
/// .path(EStr::new(""))
/// .path(EStr::EMPTY)
/// .query(&buf)
/// .build()
/// .unwrap();
Expand Down
44 changes: 20 additions & 24 deletions src/encoding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ pub trait Encoder: 'static {
/// use std::collections::HashMap;
///
/// let query = "name=%E5%BC%A0%E4%B8%89&speech=%C2%A1Ol%C3%A9%21";
/// let map: HashMap<_, _> = EStr::<Query>::new(query)
/// let map: HashMap<_, _> = EStr::<Query>::new_or_panic(query)
/// .split('&')
/// .map(|s| s.split_once('=').unwrap_or((s, EStr::new(""))))
/// .map(|s| s.split_once('=').unwrap_or((s, EStr::EMPTY)))
/// .map(|(k, v)| (k.decode().into_string_lossy(), v.decode().into_string_lossy()))
/// .collect();
/// assert_eq!(map["name"], "张三");
Expand Down Expand Up @@ -103,30 +103,26 @@ impl<E: Encoder> EStr<E> {
#[ref_cast_custom]
pub(crate) const fn new_validated(s: &str) -> &Self;

/// An empty `EStr` slice.
pub const EMPTY: &'static Self = Self::new_validated("");

/// Converts a string slice to an `EStr` slice.
///
/// This function *panics* on invalid input and should only be used
/// when you know that the string is properly percent-encoded.
/// If you want to build a percent-encoded string from scratch,
/// use [`EString`] instead.
///
/// # Panics
///
/// Panics if the string is not properly encoded with `E`.
/// For a non-panicking variant, use [`try_new`](Self::try_new).
/// For a non-panicking variant, use [`new`](Self::new).
#[must_use]
pub const fn new(s: &str) -> &Self {
match Self::try_new(s) {
pub const fn new_or_panic(s: &str) -> &Self {
match Self::new(s) {
Some(s) => s,
None => panic!("improperly encoded string"),
}
}

/// Converts a string slice to an `EStr` slice, returning `None` if the conversion fails.
///
/// This is the non-panicking variant of [`new`](Self::new).
#[must_use]
pub const fn try_new(s: &str) -> Option<&Self> {
pub const fn new(s: &str) -> Option<&Self> {
if E::TABLE.validate(s.as_bytes()) {
Some(EStr::new_validated(s))
} else {
Expand Down Expand Up @@ -184,7 +180,7 @@ impl<E: Encoder> EStr<E> {
/// ```
/// use fluent_uri::encoding::{encoder::Path, EStr};
///
/// let dec = EStr::<Path>::new("%C2%A1Hola%21").decode();
/// let dec = EStr::<Path>::new_or_panic("%C2%A1Hola%21").decode();
/// assert_eq!(dec.as_bytes(), &[0xc2, 0xa1, 0x48, 0x6f, 0x6c, 0x61, 0x21]);
/// assert_eq!(dec.into_string()?, "¡Hola!");
/// # Ok::<_, std::string::FromUtf8Error>(())
Expand Down Expand Up @@ -212,9 +208,9 @@ impl<E: Encoder> EStr<E> {
/// ```
/// use fluent_uri::encoding::{encoder::Path, EStr};
///
/// assert!(EStr::<Path>::new("a,b,c").split(',').eq(["a", "b", "c"]));
/// assert!(EStr::<Path>::new(",").split(',').eq(["", ""]));
/// assert!(EStr::<Path>::new("").split(',').eq([""]));
/// assert!(EStr::<Path>::new_or_panic("a,b,c").split(',').eq(["a", "b", "c"]));
/// assert!(EStr::<Path>::new_or_panic(",").split(',').eq(["", ""]));
/// assert!(EStr::<Path>::EMPTY.split(',').eq([""]));
/// ```
pub fn split(&self, delim: char) -> Split<'_, E> {
assert!(
Expand Down Expand Up @@ -244,11 +240,11 @@ impl<E: Encoder> EStr<E> {
/// use fluent_uri::encoding::{encoder::Path, EStr};
///
/// assert_eq!(
/// EStr::<Path>::new("foo;bar;baz").split_once(';'),
/// Some((EStr::new("foo"), EStr::new("bar;baz")))
/// EStr::<Path>::new_or_panic("foo;bar;baz").split_once(';'),
/// Some((EStr::new_or_panic("foo"), EStr::new_or_panic("bar;baz")))
/// );
///
/// assert_eq!(EStr::<Path>::new("foo").split_once(';'), None);
/// assert_eq!(EStr::<Path>::new_or_panic("foo").split_once(';'), None);
/// ```
#[must_use]
pub fn split_once(&self, delim: char) -> Option<(&Self, &Self)> {
Expand Down Expand Up @@ -278,11 +274,11 @@ impl<E: Encoder> EStr<E> {
/// use fluent_uri::encoding::{encoder::Path, EStr};
///
/// assert_eq!(
/// EStr::<Path>::new("foo;bar;baz").rsplit_once(';'),
/// Some((EStr::new("foo;bar"), EStr::new("baz")))
/// EStr::<Path>::new_or_panic("foo;bar;baz").rsplit_once(';'),
/// Some((EStr::new_or_panic("foo;bar"), EStr::new_or_panic("baz")))
/// );
///
/// assert_eq!(EStr::<Path>::new("foo").rsplit_once(';'), None);
/// assert_eq!(EStr::<Path>::new_or_panic("foo").rsplit_once(';'), None);
/// ```
#[must_use]
pub fn rsplit_once(&self, delim: char) -> Option<(&Self, &Self)> {
Expand Down Expand Up @@ -349,7 +345,7 @@ impl<E: Encoder> Ord for EStr<E> {
impl<E: Encoder> Default for &EStr<E> {
/// Creates an empty `EStr` slice.
fn default() -> Self {
EStr::new_validated("")
EStr::EMPTY
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ use internal::{Meta, ToUri, Value};
///
/// let uri = Uri::parse("http://user@example.com:8042/over/there?name=ferret#nose")?;
///
/// assert_eq!(uri.scheme().unwrap(), Scheme::new("http"));
/// assert_eq!(uri.scheme().unwrap(), Scheme::new_or_panic("http"));
///
/// let auth = uri.authority().unwrap();
/// assert_eq!(auth.as_str(), "user@example.com:8042");
Expand Down Expand Up @@ -283,7 +283,7 @@ impl<'i, 'o, T: BorrowOrShare<'i, 'o, str>> Uri<T> {
/// use fluent_uri::{component::Scheme, Uri};
///
/// let uri = Uri::parse("http://example.com/")?;
/// assert_eq!(uri.scheme(), Some(Scheme::new("http")));
/// assert_eq!(uri.scheme(), Some(Scheme::new_or_panic("http")));
///
/// let uri = Uri::parse("/path/to/file")?;
/// assert_eq!(uri.scheme(), None);
Expand Down Expand Up @@ -359,7 +359,7 @@ impl<'i, 'o, T: BorrowOrShare<'i, 'o, str>> Uri<T> {
/// use fluent_uri::{encoding::EStr, Uri};
///
/// let uri = Uri::parse("http://example.com/?lang=en")?;
/// assert_eq!(uri.query(), Some(EStr::new("lang=en")));
/// assert_eq!(uri.query(), Some(EStr::new_or_panic("lang=en")));
///
/// let uri = Uri::parse("ftp://192.0.2.1/")?;
/// assert_eq!(uri.query(), None);
Expand All @@ -386,7 +386,7 @@ impl<'i, 'o, T: BorrowOrShare<'i, 'o, str>> Uri<T> {
/// use fluent_uri::{encoding::EStr, Uri};
///
/// let uri = Uri::parse("http://example.com/#usage")?;
/// assert_eq!(uri.fragment(), Some(EStr::new("usage")));
/// assert_eq!(uri.fragment(), Some(EStr::new_or_panic("usage")));
///
/// let uri = Uri::parse("ftp://192.0.2.1/")?;
/// assert_eq!(uri.fragment(), None);
Expand Down
12 changes: 6 additions & 6 deletions tests/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn parse_absolute() {
));
assert_eq!(a.port(), None);
assert_eq!(u.path(), "/c=GB");
assert_eq!(u.query(), Some(EStr::new("objectClass?one")));
assert_eq!(u.query(), Some(EStr::new_or_panic("objectClass?one")));
assert_eq!(u.fragment(), None);

let u = Uri::parse("mailto:John.Doe@example.com").unwrap();
Expand Down Expand Up @@ -108,16 +108,16 @@ fn parse_absolute() {
assert!(matches!(a.host_parsed(), Host::RegName(name) if name == "example.com"));
assert_eq!(a.port(), Some("8042"));
assert_eq!(u.path(), "/over/there");
assert_eq!(u.query(), Some(EStr::new("name=ferret")));
assert_eq!(u.fragment(), Some(EStr::new("nose")));
assert_eq!(u.query(), Some(EStr::new_or_panic("name=ferret")));
assert_eq!(u.fragment(), Some(EStr::new_or_panic("nose")));

let u = Uri::parse("ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm").unwrap();
assert_eq!(u.scheme().unwrap().as_str(), "ftp");
let a = u.authority().unwrap();
assert_eq!(a.as_str(), "cnn.example.com&story=breaking_news@10.0.0.1");
assert_eq!(
a.userinfo(),
Some(EStr::new("cnn.example.com&story=breaking_news"))
Some(EStr::new_or_panic("cnn.example.com&story=breaking_news"))
);
assert_eq!(a.host(), "10.0.0.1");
#[cfg(feature = "net")]
Expand Down Expand Up @@ -225,15 +225,15 @@ fn parse_relative() {
assert!(u.scheme().is_none());
assert!(u.authority().is_none());
assert_eq!(u.path(), "");
assert_eq!(u.query(), Some(EStr::new("query")));
assert_eq!(u.query(), Some(EStr::new_or_panic("query")));
assert_eq!(u.fragment(), None);

let u = Uri::parse("#fragment").unwrap();
assert!(u.scheme().is_none());
assert!(u.authority().is_none());
assert_eq!(u.path(), "");
assert_eq!(u.query(), None);
assert_eq!(u.fragment(), Some(EStr::new("fragment")));
assert_eq!(u.fragment(), Some(EStr::new_or_panic("fragment")));
}

#[test]
Expand Down

0 comments on commit 1410d8e

Please sign in to comment.