Skip to content

Commit

Permalink
Switch to mime::Mime for MediaRange
Browse files Browse the repository at this point in the history
  • Loading branch information
wafflespeanut committed Jun 13, 2020
1 parent 6fb9679 commit a64059c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 14 deletions.
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ chrono = { version = "0", optional = true }
heck = { version = "0.3", optional = true }
lazy_static = "1.3"
log = { version = "0.4", optional = true }
mime = { git = "https://github.com/hyperium/mime", rev = "938484de95445a2af931515d2b7252612c575da7", features = ["serde1"] }
mime = "0.3"
paperclip-macros = { path = "../macros", version = "0.3.0" }
parking_lot = { version = "0.10", features = ["serde"] }
rust_decimal = { version = "1", optional = true }
Expand Down
32 changes: 25 additions & 7 deletions core/src/v2/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};

use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::fmt;
use std::ops::{Deref, DerefMut};
use std::sync::Arc;

lazy_static! {
/// Media range for JSON.
pub static ref JSON_MIME: MediaRange =
MediaRange(mime::MediaRange::parse("application/json").expect("parsing mime"));
MediaRange("application/json".parse().expect("parsing mime"));
/// Default coder for JSON.
pub static ref JSON_CODER: Arc<Coder> = Arc::new(Coder {
encoder_path: "serde_json::to_writer".into(),
Expand All @@ -21,7 +22,7 @@ lazy_static! {
});
/// Media range for YAML.
pub static ref YAML_MIME: MediaRange =
MediaRange(mime::MediaRange::parse("application/yaml").expect("parsing mime"));
MediaRange("application/yaml".parse().expect("parsing mime"));
/// Default coder for YAML.
pub static ref YAML_CODER: Arc<Coder> = Arc::new(Coder {
encoder_path: "serde_yaml::to_writer".into(),
Expand All @@ -35,14 +36,14 @@ lazy_static! {

/// Wrapper for `mime::MediaRange` to support `BTree{Set, Map}`.
#[derive(Debug, Clone)]
pub struct MediaRange(pub mime::MediaRange);
pub struct MediaRange(pub mime::Mime);

#[cfg(feature = "codegen")]
impl MediaRange {
/// Implementation from https://github.com/hyperium/mime/blob/65ea9c3d0cad4cb548b41124050c545120134035/src/range.rs#L155
fn matches_params(&self, r: &Self) -> bool {
for (name, value) in self.0.params() {
if name != "q" && r.0.param(name) != Some(value) {
if name != "q" && r.0.get_param(name) != Some(value) {
return false;
}
}
Expand All @@ -51,7 +52,7 @@ impl MediaRange {
}
}

/// `x-coder` global extension for custom encoders and decoders.
/// `x-rust-coders` global extension for custom encoders and decoders.
#[derive(Debug, Default, Clone)]
pub struct Coders(BTreeMap<MediaRange, Arc<Coder>>);

Expand Down Expand Up @@ -140,7 +141,7 @@ impl Serialize for MediaRange {
where
S: Serializer,
{
self.0.serialize(serializer)
serializer.serialize_str(self.0.as_ref())
}
}

Expand All @@ -149,7 +150,24 @@ impl<'de> Deserialize<'de> for MediaRange {
where
D: Deserializer<'de>,
{
Ok(MediaRange(mime::MediaRange::deserialize(deserializer)?))
struct Visitor;

impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = MediaRange;

fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("a valid media range")
}

fn visit_str<E>(self, value: &str) -> Result<MediaRange, E>
where
E: serde::de::Error,
{
value.parse().map_err(E::custom).map(MediaRange)
}
}

deserializer.deserialize_str(Visitor)
}
}

Expand Down
24 changes: 18 additions & 6 deletions core/src/v2/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ pub struct Api<P, R, S> {
pub tags: Vec<Tag>,
#[serde(rename = "externalDocs", skip_serializing_if = "Option::is_none")]
pub external_docs: Option<ExternalDocs>,
/// Extension for custom coders to be used for decoding API objects.
///
/// An example for JSON would be:
/// ```yaml
/// x-rust-coders:
/// application/json:
/// encoder_path: serde_json::to_writer
/// decoder_path: serde_json::from_reader
/// any_value: serde_json::Value
/// error_path: serde_json::Error
/// ```
/// **NOTE:** JSON and YAML encodings are already supported.
#[serde(
default,
rename = "x-rust-coders",
Expand All @@ -129,13 +141,13 @@ pub struct Api<P, R, S> {
///
/// The key is the LHS of a dependency, which is the crate name.
/// The value is the RHS of a crate's requirements as it would appear
/// in the manifest. Note that the caller must add proper quoting
/// whenever required.
/// in the manifest. Note that the caller must add proper escaping
/// wherever required.
///
/// For example, in a JSON spec, the following are all valid:
/// - `{"my_crate": "0.7"}`
/// - `{"my_crate": "{ git = \"git://foo.bar/repo\" }"}`
/// - `{"my_crate": "{ version = \"0.9\", features = [\"booya\"] }"}`
/// For example, the following are all valid:
/// - `my_crate: "0.7"`
/// - `my_crate: "{ git = \"git://foo.bar/repo\" }"`
/// - `my_crate: "{ version = \"0.9\", features = [\"booya\"] }"`
#[serde(
default,
rename = "x-rust-dependencies",
Expand Down

0 comments on commit a64059c

Please sign in to comment.