Skip to content

Commit

Permalink
Add IsbnRef to avoid exposing internal API
Browse files Browse the repository at this point in the history
  • Loading branch information
philippeitis committed Oct 3, 2021
1 parent 66a985f commit bf18b04
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 27 deletions.
57 changes: 34 additions & 23 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ pub type IsbnResult<T> = Result<T, IsbnError>;

include!(concat!(env!("OUT_DIR"), "/generated.rs"));

pub struct Group<'a> {
struct Group<'a> {
name: &'a str,
segment_length: usize,
}

pub trait IsbnObject {
trait IsbnObject {
fn ean_ucc_group(&self) -> Result<Group, IsbnError> {
Isbn::get_ean_ucc_group(self.prefix_element(), self.segment(0))
}
Expand Down Expand Up @@ -156,33 +156,44 @@ impl Isbn {
}
}

impl IsbnObject for Isbn {
fn hyphenate_with(&self, hyphen_at: [usize; 2]) -> ArrayString<17> {
match self {
Isbn::_10(isbn) => isbn.hyphenate_with(hyphen_at),
Isbn::_13(isbn) => isbn.hyphenate_with(hyphen_at),
}
}
/// An International Standard Book Number, either ISBN10 or ISBN13.
///
/// # Examples
///
/// ```
/// use isbn2::{Isbn, Isbn10, Isbn13};
///
/// let isbn_10 = Isbn::_10(Isbn10::new([8, 9, 6, 6, 2, 6, 1, 2, 6, 4]).unwrap());
/// let isbn_13 = Isbn::_13(Isbn13::new([9, 7, 8, 1, 4, 9, 2, 0, 6, 7, 6, 6, 5]).unwrap());
///
/// assert_eq!("89-6626-126-4".parse(), Ok(isbn_10));
/// assert_eq!("978-1-4920-6766-5".parse(), Ok(isbn_13));
/// ```
#[derive(Debug, PartialEq, Clone, Eq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub enum IsbnRef<'a> {
_10(&'a Isbn10),
_13(&'a Isbn13),
}

fn prefix_element(&self) -> u16 {
match self {
Isbn::_10(isbn) => isbn.prefix_element(),
Isbn::_13(isbn) => isbn.prefix_element(),
impl<'a> From<&'a Isbn> for IsbnRef<'a> {
fn from(isbn: &'a Isbn) -> Self {
match isbn {
Isbn::_10(isbn) => isbn.into(),
Isbn::_13(isbn) => isbn.into()
}
}
}

fn segment(&self, base: usize) -> u32 {
match self {
Isbn::_10(isbn) => isbn.segment(base),
Isbn::_13(isbn) => isbn.segment(base),
}
impl<'a> From<&'a Isbn10> for IsbnRef<'a> {
fn from(isbn: &'a Isbn10) -> Self {
IsbnRef::_10(isbn)
}
}

fn group_prefix(&self, length: usize) -> u32 {
match self {
Isbn::_10(isbn) => isbn.group_prefix(length),
Isbn::_13(isbn) => isbn.group_prefix(length),
}
impl<'a> From<&'a Isbn13> for IsbnRef<'a> {
fn from(isbn: &'a Isbn13) -> Self {
IsbnRef::_13(isbn)
}
}

Expand Down
23 changes: 19 additions & 4 deletions src/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use arrayvec::ArrayString;
use indexmap::IndexMap;
use quick_xml::{events::Event, Reader};

use crate::{Group, Isbn, Isbn10, Isbn13, IsbnError, IsbnObject};
use crate::{Group, IsbnError, IsbnObject, IsbnRef};

struct Segment {
name: String,
Expand Down Expand Up @@ -300,7 +300,7 @@ impl IsbnRange {
/// # Errors
/// If the RangeMessage is in an unexpected format or does not exist, an error will be returned.
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, IsbnRangeError> {
let reader = BufReader::new(File::open("isbn-ranges/RangeMessage.xml")?);
let reader = BufReader::new(File::open(path)?);
Self::from_reader(reader)
}

Expand Down Expand Up @@ -413,7 +413,14 @@ impl IsbnRange {
/// # Errors
/// If the ISBN is not valid, as determined by the current ISBN rules, an error will be
/// returned.
pub fn hyphenate<I: IsbnObject>(&self, isbn: &I) -> Result<ArrayString<17>, IsbnError> {
pub fn hyphenate<'a, I: Into<IsbnRef<'a>>>(&self, isbn: I) -> Result<ArrayString<17>, IsbnError> {
match isbn.into() {
IsbnRef::_10(isbn) => self.hyphenate_isbn(isbn),
IsbnRef::_13(isbn) => self.hyphenate_isbn(isbn),
}
}

fn hyphenate_isbn<I: IsbnObject>(&self, isbn: &I) -> Result<ArrayString<17>, IsbnError> {
let segment = self
.ean_ucc_group
.get(&isbn.prefix_element())
Expand Down Expand Up @@ -455,7 +462,14 @@ impl IsbnRange {
/// # Errors
/// If the ISBN is not valid, as determined by `self`, an error will be
/// returned.
pub fn get_registration_group<I: IsbnObject>(&self, isbn: &I) -> Result<&str, IsbnError> {
pub fn get_registration_group<'a, I: Into<IsbnRef<'a>>>(&self, isbn: I) -> Result<&str, IsbnError> {
match isbn.into() {
IsbnRef::_10(isbn) => self.get_registration_group_isbn(isbn),
IsbnRef::_13(isbn) => self.get_registration_group_isbn(isbn),
}
}

fn get_registration_group_isbn<I: IsbnObject>(&self, isbn: &I) -> Result<&str, IsbnError> {
let segment = self
.ean_ucc_group
.get(&isbn.prefix_element())
Expand Down Expand Up @@ -494,6 +508,7 @@ impl IsbnRange {

#[cfg(test)]
mod test {
use crate::Isbn;
use super::*;

#[test]
Expand Down

0 comments on commit bf18b04

Please sign in to comment.