diff options
| author | Christine Dodrill <me@christine.website> | 2021-01-14 22:36:34 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-14 22:36:34 -0500 |
| commit | d2455aa1c1bfc599a07966a7d717c1380d41bbc0 (patch) | |
| tree | c2b206aa41cd6f0e13d61b5455861f09ab5d1304 /lib/jsonfeed | |
| parent | a359f54a91f4aeb914c69f59a02afabccd72450e (diff) | |
| download | xesite-d2455aa1c1bfc599a07966a7d717c1380d41bbc0.tar.xz xesite-d2455aa1c1bfc599a07966a7d717c1380d41bbc0.zip | |
Cache better (#296)
* Many improvements around bandwidth use
- Use ETags for RSS/Atom feeds
- Use cache-control headers
- Update to rust nightly (for rust-analyzer and faster builds)
- Limit feeds to the last 20 posts:
https://twitter.com/theprincessxena/status/1349891678857998339
- Use if-none-match to limit bandwidth further
Also does this:
- bump go_vanity to 0.3.0 and lets users customize the branch name
- fix formatting on jsonfeed
- remove last vestige of kubernetes/docker support
Signed-off-by: Christine Dodrill <me@christine.website>
* expire cache quicker for dynamic pages
Signed-off-by: Christine Dodrill <me@christine.website>
* add rss ttl
Signed-off-by: Christine Dodrill <me@christine.website>
* add blogpost
Signed-off-by: Christine Dodrill <me@christine.website>
Diffstat (limited to 'lib/jsonfeed')
| -rw-r--r-- | lib/jsonfeed/src/builder.rs | 11 | ||||
| -rw-r--r-- | lib/jsonfeed/src/errors.rs | 3 | ||||
| -rw-r--r-- | lib/jsonfeed/src/feed.rs | 36 | ||||
| -rw-r--r-- | lib/jsonfeed/src/item.rs | 116 | ||||
| -rw-r--r-- | lib/jsonfeed/src/lib.rs | 66 |
5 files changed, 112 insertions, 120 deletions
diff --git a/lib/jsonfeed/src/builder.rs b/lib/jsonfeed/src/builder.rs index f17740f..640a280 100644 --- a/lib/jsonfeed/src/builder.rs +++ b/lib/jsonfeed/src/builder.rs @@ -1,7 +1,7 @@ use std::default::Default; use errors::*; -use feed::{Feed, Author, Attachment}; +use feed::{Attachment, Author, Feed}; use item::{Content, Item}; /// Feed Builder @@ -160,7 +160,7 @@ impl ItemBuilder { match self.content { Some(Content::Text(t)) => { self.content = Some(Content::Both(i.into(), t)); - }, + } _ => { self.content = Some(Content::Html(i.into())); } @@ -172,10 +172,10 @@ impl ItemBuilder { match self.content { Some(Content::Html(s)) => { self.content = Some(Content::Both(s, i.into())); - }, + } _ => { self.content = Some(Content::Text(i.into())); - }, + } } self } @@ -197,8 +197,7 @@ impl ItemBuilder { date_modified: self.date_modified, author: self.author, tags: self.tags, - attachments: self.attachments + attachments: self.attachments, }) } } - diff --git a/lib/jsonfeed/src/errors.rs b/lib/jsonfeed/src/errors.rs index 936b7ec..b94779c 100644 --- a/lib/jsonfeed/src/errors.rs +++ b/lib/jsonfeed/src/errors.rs @@ -1,7 +1,6 @@ use serde_json; -error_chain!{ +error_chain! { foreign_links { Serde(serde_json::Error); } } - diff --git a/lib/jsonfeed/src/feed.rs b/lib/jsonfeed/src/feed.rs index 8b5b5ce..320feb6 100644 --- a/lib/jsonfeed/src/feed.rs +++ b/lib/jsonfeed/src/feed.rs @@ -1,7 +1,7 @@ use std::default::Default; -use item::Item; use builder::Builder; +use item::Item; const VERSION_1: &'static str = "https://jsonfeed.org/version/1"; @@ -145,9 +145,9 @@ pub struct Hub { #[cfg(test)] mod tests { + use super::*; use serde_json; use std::default::Default; - use super::*; #[test] fn serialize_feed() { @@ -168,18 +168,16 @@ mod tests { #[test] fn deserialize_feed() { - let json = r#"{"version":"https://jsonfeed.org/version/1","title":"some title","items":[]}"#; + let json = + r#"{"version":"https://jsonfeed.org/version/1","title":"some title","items":[]}"#; let feed: Feed = serde_json::from_str(&json).unwrap(); let expected = Feed { version: "https://jsonfeed.org/version/1".to_string(), - title: "some title".to_string(), - items: vec![], - ..Default::default() + title: "some title".to_string(), + items: vec![], + ..Default::default() }; - assert_eq!( - feed, - expected - ); + assert_eq!(feed, expected); } #[test] @@ -208,10 +206,7 @@ mod tests { size_in_bytes: Some(1), duration_in_seconds: Some(1), }; - assert_eq!( - attachment, - expected - ); + assert_eq!(attachment, expected); } #[test] @@ -229,17 +224,15 @@ mod tests { #[test] fn deserialize_author() { - let json = r#"{"name":"bob jones","url":"http://example.com","avatar":"http://img.com/blah"}"#; + let json = + r#"{"name":"bob jones","url":"http://example.com","avatar":"http://img.com/blah"}"#; let author: Author = serde_json::from_str(&json).unwrap(); let expected = Author { name: Some("bob jones".to_string()), url: Some("http://example.com".to_string()), avatar: Some("http://img.com/blah".to_string()), }; - assert_eq!( - author, - expected - ); + assert_eq!(author, expected); } #[test] @@ -262,10 +255,7 @@ mod tests { type_: "some-type".to_string(), url: "http://example.com".to_string(), }; - assert_eq!( - hub, - expected - ); + assert_eq!(hub, expected); } #[test] diff --git a/lib/jsonfeed/src/item.rs b/lib/jsonfeed/src/item.rs index 605525b..0f7d6ab 100644 --- a/lib/jsonfeed/src/item.rs +++ b/lib/jsonfeed/src/item.rs @@ -1,11 +1,11 @@ -use std::fmt; use std::default::Default; +use std::fmt; -use feed::{Author, Attachment}; use builder::ItemBuilder; +use feed::{Attachment, Author}; -use serde::ser::{Serialize, Serializer, SerializeStruct}; -use serde::de::{self, Deserialize, Deserializer, Visitor, MapAccess}; +use serde::de::{self, Deserialize, Deserializer, MapAccess, Visitor}; +use serde::ser::{Serialize, SerializeStruct, Serializer}; /// Represents the `content_html` and `content_text` attributes of an item #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] @@ -61,7 +61,8 @@ impl Default for Item { impl Serialize for Item { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> - where S: Serializer + where + S: Serializer, { let mut state = serializer.serialize_struct("Item", 14)?; state.serialize_field("id", &self.id)?; @@ -78,15 +79,15 @@ impl Serialize for Item { Content::Html(ref s) => { state.serialize_field("content_html", s)?; state.serialize_field("content_text", &None::<Option<&str>>)?; - }, + } Content::Text(ref s) => { state.serialize_field("content_html", &None::<Option<&str>>)?; state.serialize_field("content_text", s)?; - }, + } Content::Both(ref s, ref t) => { state.serialize_field("content_html", s)?; state.serialize_field("content_text", t)?; - }, + } }; if self.summary.is_some() { state.serialize_field("summary", &self.summary)?; @@ -117,8 +118,9 @@ impl Serialize for Item { } impl<'de> Deserialize<'de> for Item { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where D: Deserializer<'de> + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, { enum Field { Id, @@ -135,11 +137,12 @@ impl<'de> Deserialize<'de> for Item { Author, Tags, Attachments, - }; + } impl<'de> Deserialize<'de> for Field { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { struct FieldVisitor; @@ -151,7 +154,8 @@ impl<'de> Deserialize<'de> for Item { } fn visit_str<E>(self, value: &str) -> Result<Field, E> - where E: de::Error + where + E: de::Error, { match value { "id" => Ok(Field::Id), @@ -186,7 +190,8 @@ impl<'de> Deserialize<'de> for Item { } fn visit_map<V>(self, mut map: V) -> Result<Item, V::Error> - where V: MapAccess<'de> + where + V: MapAccess<'de>, { let mut id = None; let mut url = None; @@ -210,99 +215,93 @@ impl<'de> Deserialize<'de> for Item { return Err(de::Error::duplicate_field("id")); } id = Some(map.next_value()?); - }, + } Field::Url => { if url.is_some() { return Err(de::Error::duplicate_field("url")); } url = map.next_value()?; - }, + } Field::ExternalUrl => { if external_url.is_some() { return Err(de::Error::duplicate_field("external_url")); } external_url = map.next_value()?; - }, + } Field::Title => { if title.is_some() { return Err(de::Error::duplicate_field("title")); } title = map.next_value()?; - }, + } Field::ContentHtml => { if content_html.is_some() { return Err(de::Error::duplicate_field("content_html")); } content_html = map.next_value()?; - }, + } Field::ContentText => { if content_text.is_some() { return Err(de::Error::duplicate_field("content_text")); } content_text = map.next_value()?; - }, + } Field::Summary => { if summary.is_some() { return Err(de::Error::duplicate_field("summary")); } summary = map.next_value()?; - }, + } Field::Image => { if image.is_some() { return Err(de::Error::duplicate_field("image")); } image = map.next_value()?; - }, + } Field::BannerImage => { if banner_image.is_some() { return Err(de::Error::duplicate_field("banner_image")); } banner_image = map.next_value()?; - }, + } Field::DatePublished => { if date_published.is_some() { return Err(de::Error::duplicate_field("date_published")); } date_published = map.next_value()?; - }, + } Field::DateModified => { if date_modified.is_some() { return Err(de::Error::duplicate_field("date_modified")); } date_modified = map.next_value()?; - }, + } Field::Author => { if author.is_some() { return Err(de::Error::duplicate_field("author")); } author = map.next_value()?; - }, + } Field::Tags => { if tags.is_some() { return Err(de::Error::duplicate_field("tags")); } tags = map.next_value()?; - }, + } Field::Attachments => { if attachments.is_some() { return Err(de::Error::duplicate_field("attachments")); } attachments = map.next_value()?; - }, + } } } let id = id.ok_or_else(|| de::Error::missing_field("id"))?; let content = match (content_html, content_text) { - (Some(s), Some(t)) => { - Content::Both(s.to_string(), t.to_string()) - }, - (Some(s), _) => { - Content::Html(s.to_string()) - }, - (_, Some(t)) => { - Content::Text(t.to_string()) - }, + (Some(s), Some(t)) => Content::Both(s.to_string(), t.to_string()), + (Some(s), _) => Content::Html(s.to_string()), + (_, Some(t)) => Content::Text(t.to_string()), _ => return Err(de::Error::missing_field("content_html or content_text")), }; @@ -363,7 +362,12 @@ mod tests { banner_image: Some("http://img.com/blah".into()), date_published: Some("2017-01-01 10:00:00".into()), date_modified: Some("2017-01-01 10:00:00".into()), - author: Some(Author::new().name("bob jones").url("http://example.com").avatar("http://img.com/blah")), + author: Some( + Author::new() + .name("bob jones") + .url("http://example.com") + .avatar("http://img.com/blah"), + ), tags: Some(vec!["json".into(), "feed".into()]), attachments: Some(vec![]), }; @@ -387,7 +391,12 @@ mod tests { banner_image: Some("http://img.com/blah".into()), date_published: Some("2017-01-01 10:00:00".into()), date_modified: Some("2017-01-01 10:00:00".into()), - author: Some(Author::new().name("bob jones").url("http://example.com").avatar("http://img.com/blah")), + author: Some( + Author::new() + .name("bob jones") + .url("http://example.com") + .avatar("http://img.com/blah"), + ), tags: Some(vec!["json".into(), "feed".into()]), attachments: Some(vec![]), }; @@ -411,7 +420,12 @@ mod tests { banner_image: Some("http://img.com/blah".into()), date_published: Some("2017-01-01 10:00:00".into()), date_modified: Some("2017-01-01 10:00:00".into()), - author: Some(Author::new().name("bob jones").url("http://example.com").avatar("http://img.com/blah")), + author: Some( + Author::new() + .name("bob jones") + .url("http://example.com") + .avatar("http://img.com/blah"), + ), tags: Some(vec!["json".into(), "feed".into()]), attachments: Some(vec![]), }; @@ -437,7 +451,12 @@ mod tests { banner_image: Some("http://img.com/blah".into()), date_published: Some("2017-01-01 10:00:00".into()), date_modified: Some("2017-01-01 10:00:00".into()), - author: Some(Author::new().name("bob jones").url("http://example.com").avatar("http://img.com/blah")), + author: Some( + Author::new() + .name("bob jones") + .url("http://example.com") + .avatar("http://img.com/blah"), + ), tags: Some(vec!["json".into(), "feed".into()]), attachments: Some(vec![]), }; @@ -460,7 +479,12 @@ mod tests { banner_image: Some("http://img.com/blah".into()), date_published: Some("2017-01-01 10:00:00".into()), date_modified: Some("2017-01-01 10:00:00".into()), - author: Some(Author::new().name("bob jones").url("http://example.com").avatar("http://img.com/blah")), + author: Some( + Author::new() + .name("bob jones") + .url("http://example.com") + .avatar("http://img.com/blah"), + ), tags: Some(vec!["json".into(), "feed".into()]), attachments: Some(vec![]), }; @@ -483,11 +507,15 @@ mod tests { banner_image: Some("http://img.com/blah".into()), date_published: Some("2017-01-01 10:00:00".into()), date_modified: Some("2017-01-01 10:00:00".into()), - author: Some(Author::new().name("bob jones").url("http://example.com").avatar("http://img.com/blah")), + author: Some( + Author::new() + .name("bob jones") + .url("http://example.com") + .avatar("http://img.com/blah"), + ), tags: Some(vec!["json".into(), "feed".into()]), attachments: Some(vec![]), }; assert_eq!(item, expected); } } - diff --git a/lib/jsonfeed/src/lib.rs b/lib/jsonfeed/src/lib.rs index bc1d94e..812083e 100644 --- a/lib/jsonfeed/src/lib.rs +++ b/lib/jsonfeed/src/lib.rs @@ -2,7 +2,7 @@ //! instead of XML //! //! This crate can serialize and deserialize between JSON Feed strings -//! and Rust data structures. It also allows for programmatically building +//! and Rust data structures. It also allows for programmatically building //! a JSON Feed //! //! Example: @@ -40,18 +40,20 @@ //! ``` extern crate serde; -#[macro_use] extern crate error_chain; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate error_chain; +#[macro_use] +extern crate serde_derive; extern crate serde_json; +mod builder; mod errors; -mod item; mod feed; -mod builder; +mod item; pub use errors::*; +pub use feed::{Attachment, Author, Feed}; pub use item::*; -pub use feed::{Feed, Author, Attachment}; use std::io::Write; @@ -116,14 +118,16 @@ pub fn to_vec_pretty(value: &Feed) -> Result<Vec<u8>> { /// Serialize a Feed to JSON and output to an IO stream pub fn to_writer<W>(writer: W, value: &Feed) -> Result<()> - where W: Write +where + W: Write, { Ok(serde_json::to_writer(writer, value)?) } /// Serialize a Feed to pretty-printed JSON and output to an IO stream pub fn to_writer_pretty<W>(writer: W, value: &Feed) -> Result<()> - where W: Write +where + W: Write, { Ok(serde_json::to_writer_pretty(writer, value)?) } @@ -137,10 +141,7 @@ mod tests { fn from_str() { let feed = r#"{"version": "https://jsonfeed.org/version/1","title":"","items":[]}"#; let expected = Feed::default(); - assert_eq!( - super::from_str(&feed).unwrap(), - expected - ); + assert_eq!(super::from_str(&feed).unwrap(), expected); } #[test] fn from_reader() { @@ -148,39 +149,27 @@ mod tests { let feed = feed.as_bytes(); let feed = Cursor::new(feed); let expected = Feed::default(); - assert_eq!( - super::from_reader(feed).unwrap(), - expected - ); + assert_eq!(super::from_reader(feed).unwrap(), expected); } #[test] fn from_slice() { let feed = r#"{"version": "https://jsonfeed.org/version/1","title":"","items":[]}"#; let feed = feed.as_bytes(); let expected = Feed::default(); - assert_eq!( - super::from_slice(&feed).unwrap(), - expected - ); + assert_eq!(super::from_slice(&feed).unwrap(), expected); } #[test] fn from_value() { let feed = r#"{"version": "https://jsonfeed.org/version/1","title":"","items":[]}"#; let feed: serde_json::Value = serde_json::from_str(&feed).unwrap(); let expected = Feed::default(); - assert_eq!( - super::from_value(feed).unwrap(), - expected - ); + assert_eq!(super::from_value(feed).unwrap(), expected); } #[test] fn to_string() { let feed = Feed::default(); let expected = r#"{"version":"https://jsonfeed.org/version/1","title":"","items":[]}"#; - assert_eq!( - super::to_string(&feed).unwrap(), - expected - ); + assert_eq!(super::to_string(&feed).unwrap(), expected); } #[test] fn to_string_pretty() { @@ -190,28 +179,19 @@ mod tests { "title": "", "items": [] }"#; - assert_eq!( - super::to_string_pretty(&feed).unwrap(), - expected - ); + assert_eq!(super::to_string_pretty(&feed).unwrap(), expected); } #[test] fn to_value() { let feed = r#"{"version":"https://jsonfeed.org/version/1","title":"","items":[]}"#; let expected: serde_json::Value = serde_json::from_str(&feed).unwrap(); - assert_eq!( - super::to_value(Feed::default()).unwrap(), - expected - ); + assert_eq!(super::to_value(Feed::default()).unwrap(), expected); } #[test] fn to_vec() { let feed = r#"{"version":"https://jsonfeed.org/version/1","title":"","items":[]}"#; let expected = feed.as_bytes(); - assert_eq!( - super::to_vec(&Feed::default()).unwrap(), - expected - ); + assert_eq!(super::to_vec(&Feed::default()).unwrap(), expected); } #[test] fn to_vec_pretty() { @@ -221,10 +201,7 @@ mod tests { "items": [] }"#; let expected = feed.as_bytes(); - assert_eq!( - super::to_vec_pretty(&Feed::default()).unwrap(), - expected - ); + assert_eq!(super::to_vec_pretty(&Feed::default()).unwrap(), expected); } #[test] fn to_writer() { @@ -249,4 +226,3 @@ mod tests { assert_eq!(result, feed); } } - |
