Skip to main content

Doi

Struct Doi 

Source
pub struct Doi(/* private fields */);
Expand description

A Digital Object Identifier, held bare (10.3886/ICPSR36966.v1).

A newtype for one reason: a DOI is rendered by prefixing https://doi.org/, and a record that had already stored the prefixed form would render https://doi.org/https://doi.org/10.…. Doi::new accepts either spelling and stores the bare one, so the prefix is applied exactly once no matter which form was written down.

§What is stored is the identifier, not a URL

The value held here is the DOI name itself, raw: 10.1234/a#b is a DOI whose suffix contains a literal #. It is never the percent-encoded form. Doi::url applies that encoding on the way out, and Doi::new undoes it when the input arrived as a resolver URL, so the two are inverses and Doi::new(d.url()) returns d.

Stating it that way round is what keeps the type coherent. The alternative — storing the encoded form — makes Doi::as_str not the identifier but a fragment of a URL, and leaves no way to tell a DOI containing a literal % from one whose % opens an escape. Recording what the thing is and transforming at the boundary is the same rule GivenName follows.

Implementations§

Source§

impl Doi

Source

pub fn new(text: &str) -> Result<Self, NotADoi>

Parse a DOI, accepting the bare form, a doi: prefix, or a https://doi.org/ (or http://, or dx.doi.org) resolver URL.

The shape checked is the one the DOI Handbook defines: a 10. prefix, a registrant code of digits (possibly dot-separated, as in 10.1000.10/123), a /, and a non-empty suffix all of whose characters are printable (is_doi_name_char). That is deliberately stricter than “starts with 10. and contains a slash”, because everything this type accepts is rendered as a resolver link — and a link that resolves to nothing is exactly the plausible-looking citation this module exists to prevent. Beyond the shape it cannot go: whether a well-formed DOI is registered is a question only the network answers, and this crate has no network by construction.

§Errors

Returns NotADoi when what remains after the prefix is not that shape.

Source

pub fn as_str(&self) -> &str

The bare DOI, with no resolver prefix.

Source

pub fn url(&self) -> String

The DOI as APA renders it: https://doi.org/10.….

The identifier is percent-encoded on the way in, because a DOI may legitimately contain characters that mean something else inside a URL. The sharpest is #: concatenated raw, 10.1234/a#b becomes https://doi.org/10.1234/a#b, whose #b is an HTTP fragment and is never sent to the resolver — so the link retrieves 10.1234/a, a different record, silently and with every appearance of working. ? opens a query string and does the same; a bare % invalidates the escape sequence it looks like.

Encoded rather than refused, and the reason is evidence rather than taste: 10.1002/(SICI)1097-0258(19970815)16:15<1707::AID-SIM605>3.0.CO;2-Y is a real registered DOI, and <, >, (, ; and : are ordinary in the wild. A suffix rule narrow enough to be URL-safe by construction would refuse identifiers that exist, which is a worse failure than encoding them. Doi::as_str still returns the DOI exactly as recorded — this is a transport encoding applied where the transport is, the same kind of operation as applying the resolver prefix, and for the same reason it is applied exactly once.

What passes through unescaped is RFC 3986’s pchar (is_url_path_safe), plus /; everything else becomes %XX. Byte by byte, so a multi-byte character is encoded as the bytes a URL actually carries.

Trait Implementations§

Source§

impl Clone for Doi

Source§

fn clone(&self) -> Doi

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Doi

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Doi

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Doi

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Doi

Source§

impl From<Doi> for String

Source§

fn from(doi: Doi) -> Self

Converts to this type from the input type.
Source§

impl Ord for Doi

Source§

fn cmp(&self, other: &Doi) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl PartialEq for Doi

Source§

fn eq(&self, other: &Doi) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialOrd for Doi

Source§

fn partial_cmp(&self, other: &Doi) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Serialize for Doi

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Doi

Source§

impl TryFrom<String> for Doi

Source§

type Error = NotADoi

The type returned in the event of a conversion error.
Source§

fn try_from(text: String) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl Freeze for Doi

§

impl RefUnwindSafe for Doi

§

impl Send for Doi

§

impl Sync for Doi

§

impl Unpin for Doi

§

impl UnsafeUnpin for Doi

§

impl UnwindSafe for Doi

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Comparable<K> for Q
where Q: Ord + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.