Rust: designing around the orphan rule for external traits

Viewed 67

I'm learning Rust by implementing an API to query a database, using Actix-web and Diesel. I want to be able to store Books, and a book looks like this:

pub struct Book {
    pub id: i32,
    pub isbn: ISBN,
    pub title: String,
    pub author: String,
    pub edition: String,
    pub created_at: chrono::NaiveDateTime,
}

The component giving me difficulties is ISBN, for which I'm using the external crate isbnid::isbn::ISBN. It doesn't implement Serialize, Deserialize, or Queryable, which I need. I have gotten around this for the serde types following this serde guide.

Unfortunately I cannot do the same for Queryable, so I end up with the error

error[E0277]: the trait bound `ISBN: diesel::Queryable<diesel::sql_types::Text, Pg>` is not satisfied

From this post I understand that I cannot implement the external trait Queryable on the external type ISBN due to the orphan rule. However, I would like my Book struct to have the ISBN type, because it provides nice functionality to do with a book's ISBN, such as verifying validity.

My question: how do I idiomatically work around this rule in my design? Is storing ISBN as a string and manually verifying ISBNs are correct the best I can do? Thanks!

0 Answers
Related