diff options
| author | Christine Dodrill <me@christine.website> | 2020-07-16 15:32:30 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-16 15:32:30 -0400 |
| commit | 385d25c9f96c0acd5d932488e3bd0ed36ceb4dd7 (patch) | |
| tree | af789f7250519b23038a7e5ea0ae7f4f4c1ffdfc /lib/jsonfeed/src/builder.rs | |
| parent | 449e934246c82d90dd0aac2644d67f928befeeb4 (diff) | |
| download | xesite-385d25c9f96c0acd5d932488e3bd0ed36ceb4dd7.tar.xz xesite-385d25c9f96c0acd5d932488e3bd0ed36ceb4dd7.zip | |
Rewrite site backend in Rust (#178)
* add shell.nix changes for Rust #176
* set up base crate layout
* add first set of dependencies
* start adding basic app modules
* start html templates
* serve index page
* add contact and feeds pages
* add resume rendering support
* resume cleanups
* get signalboost page working
* rewrite config to be in dhall
* more work
* basic generic post loading
* more tests
* initial blog index support
* fix routing?
* render blogposts
* X-Clacks-Overhead
* split blog handlers into blog.rs
* gallery index
* gallery posts
* fix hashtags
* remove instantpage (it messes up the metrics)
* talk support + prometheus
* Create rust.yml
* Update rust.yml
* Update codeql-analysis.yml
* add jsonfeed library
* jsonfeed support
* rss/atom
* go mod tidy
* atom: add posted date
* rss: add publishing date
* nix: build rust program
* rip out go code
* rip out go templates
* prepare for serving in docker
* create kubernetes deployment
* create automagic deployment
* build docker images on non-master
* more fixes
* fix timestamps
* fix RSS/Atom/JSONFeed validation errors
* add go vanity import redirecting
* templates/header: remove this
* atom feed: fixes
* fix?
* fix??
* fix rust tests
* Update rust.yml
* automatically show snow during the winter
* fix dates
* show commit link in footer
* sitemap support
* fix compiler warning
* start basic patreon client
* integrate kankyo
* fix patreon client
* add patrons page
* remove this
* handle patron errors better
* fix build
* clean up deploy
* sort envvars for deploy
* remove deps.nix
* shell.nix: remove go
* update README
* fix envvars for tests
* nice
* blog: add rewrite in rust post
* blog/site-update: more words
Diffstat (limited to 'lib/jsonfeed/src/builder.rs')
| -rw-r--r-- | lib/jsonfeed/src/builder.rs | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/lib/jsonfeed/src/builder.rs b/lib/jsonfeed/src/builder.rs new file mode 100644 index 0000000..f17740f --- /dev/null +++ b/lib/jsonfeed/src/builder.rs @@ -0,0 +1,204 @@ +use std::default::Default; + +use errors::*; +use feed::{Feed, Author, Attachment}; +use item::{Content, Item}; + +/// Feed Builder +/// +/// This is used to programmatically build up a Feed object, +/// which can be serialized later into a JSON string +pub struct Builder(Feed); + +impl Builder { + pub fn new() -> Builder { + Builder(Feed::default()) + } + + pub fn title<I: Into<String>>(mut self, t: I) -> Builder { + self.0.title = t.into(); + self + } + + pub fn home_page_url<I: Into<String>>(mut self, url: I) -> Builder { + self.0.home_page_url = Some(url.into()); + self + } + + pub fn feed_url<I: Into<String>>(mut self, url: I) -> Builder { + self.0.feed_url = Some(url.into()); + self + } + + pub fn description<I: Into<String>>(mut self, desc: I) -> Builder { + self.0.description = Some(desc.into()); + self + } + + pub fn user_comment<I: Into<String>>(mut self, cmt: I) -> Builder { + self.0.user_comment = Some(cmt.into()); + self + } + + pub fn next_url<I: Into<String>>(mut self, url: I) -> Builder { + self.0.next_url = Some(url.into()); + self + } + + pub fn icon<I: Into<String>>(mut self, url: I) -> Builder { + self.0.icon = Some(url.into()); + self + } + + pub fn favicon<I: Into<String>>(mut self, url: I) -> Builder { + self.0.favicon = Some(url.into()); + self + } + + pub fn author(mut self, author: Author) -> Builder { + self.0.author = Some(author); + self + } + + pub fn expired(mut self) -> Builder { + self.0.expired = Some(true); + self + } + + pub fn item(mut self, item: Item) -> Builder { + self.0.items.push(item); + self + } + + pub fn build(self) -> Feed { + self.0 + } +} + +/// Builder object for an item in a feed +pub struct ItemBuilder { + pub id: Option<String>, + pub url: Option<String>, + pub external_url: Option<String>, + pub title: Option<String>, + pub content: Option<Content>, + pub summary: Option<String>, + pub image: Option<String>, + pub banner_image: Option<String>, + pub date_published: Option<String>, + pub date_modified: Option<String>, + pub author: Option<Author>, + pub tags: Option<Vec<String>>, + pub attachments: Option<Vec<Attachment>>, +} + +impl ItemBuilder { + pub fn new() -> ItemBuilder { + ItemBuilder { + id: None, + url: None, + external_url: None, + title: None, + content: None, + summary: None, + image: None, + banner_image: None, + date_published: None, + date_modified: None, + author: None, + tags: None, + attachments: None, + } + } + + pub fn title<I: Into<String>>(mut self, i: I) -> ItemBuilder { + self.title = Some(i.into()); + self + } + + pub fn image<I: Into<String>>(mut self, i: I) -> ItemBuilder { + self.image = Some(i.into()); + self + } + + pub fn id<I: Into<String>>(mut self, i: I) -> ItemBuilder { + self.id = Some(i.into()); + self + } + + pub fn url<I: Into<String>>(mut self, i: I) -> ItemBuilder { + self.url = Some(i.into()); + self + } + + pub fn external_url<I: Into<String>>(mut self, i: I) -> ItemBuilder { + self.external_url = Some(i.into()); + self + } + + pub fn date_modified<I: Into<String>>(mut self, i: I) -> ItemBuilder { + self.date_modified = Some(i.into()); + self + } + + pub fn date_published<I: Into<String>>(mut self, i: I) -> ItemBuilder { + self.date_published = Some(i.into()); + self + } + + pub fn tags(mut self, tags: Vec<String>) -> ItemBuilder { + self.tags = Some(tags); + self + } + + pub fn author(mut self, who: Author) -> ItemBuilder { + self.author = Some(who); + self + } + + pub fn content_html<I: Into<String>>(mut self, i: I) -> ItemBuilder { + match self.content { + Some(Content::Text(t)) => { + self.content = Some(Content::Both(i.into(), t)); + }, + _ => { + self.content = Some(Content::Html(i.into())); + } + } + self + } + + pub fn content_text<I: Into<String>>(mut self, i: I) -> ItemBuilder { + match self.content { + Some(Content::Html(s)) => { + self.content = Some(Content::Both(s, i.into())); + }, + _ => { + self.content = Some(Content::Text(i.into())); + }, + } + self + } + + pub fn build(self) -> Result<Item> { + if self.id.is_none() || self.content.is_none() { + return Err("missing field 'id' or 'content_*'".into()); + } + Ok(Item { + id: self.id.unwrap(), + url: self.url, + external_url: self.external_url, + title: self.title, + content: self.content.unwrap(), + summary: self.summary, + image: self.image, + banner_image: self.banner_image, + date_published: self.date_published, + date_modified: self.date_modified, + author: self.author, + tags: self.tags, + attachments: self.attachments + }) + } +} + |
