Last active
December 11, 2019 21:08
-
-
Save Geobert/1c6fffd806c019dd79cffe66a1beacf1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io::Write; | |
use std::sync::Arc; | |
use liquid::compiler::{Language, ParseTag, TagReflection, TagTokenIter, TryMatchToken}; | |
use liquid::error::Result; | |
use liquid::interpreter::{Context, PartialStore, Renderable}; | |
use liquid::partials::{InMemorySource, LazyCompiler, PartialCompiler}; | |
use liquid::value::Value; | |
#[derive(Debug)] | |
struct Youtube { | |
id: String, | |
class: Option<String>, | |
partial: Box<dyn PartialStore + Send + Sync>, | |
} | |
impl Renderable for Youtube { | |
fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> { | |
context.run_in_scope(|mut scope| -> Result<()> { | |
let stack = scope.stack_mut(); | |
stack.set("id", Value::scalar(self.id.clone())); | |
if let Some(class) = &self.class { | |
stack.set("class", Value::scalar(class.clone())); | |
} | |
let partial = self.partial.get("youtube_snippet")?; | |
partial.render_to(writer, &mut scope)?; | |
Ok(()) | |
})?; | |
Ok(()) | |
} | |
} | |
#[derive(Copy, Clone, Debug, Default)] | |
pub struct YoutubeTag {} | |
impl YoutubeTag { | |
pub fn new() -> Self { | |
Self::default() | |
} | |
} | |
impl TagReflection for YoutubeTag { | |
fn tag(&self) -> &'static str { | |
"youtube" | |
} | |
fn description(&self) -> &'static str { | |
"shortcode for embedding YouTube videos" | |
} | |
} | |
impl ParseTag for YoutubeTag { | |
fn parse( | |
&self, | |
mut arguments: TagTokenIter, | |
options: &Language, | |
) -> Result<Box<dyn Renderable>> { | |
let id = arguments.expect_next("YouTube video's id expected.")?; | |
let id = match id.expect_literal() { | |
TryMatchToken::Matches(id) => id.to_str().to_string(), | |
TryMatchToken::Fails(id) => id.as_str().to_string(), | |
}; | |
dbg!(&id); | |
let class = if let Ok(class) = arguments.expect_next("") { | |
let c = match class.expect_literal() { | |
TryMatchToken::Matches(c) => c.to_str().to_string(), | |
TryMatchToken::Fails(c) => c.as_str().to_string(), | |
}; | |
Some(c) | |
} else { | |
None | |
}; | |
dbg!(&class); | |
arguments.expect_nothing()?; | |
let snippet = r#"<div {% if class %}class="{{ class }}"{% endif %}> | |
<iframe src="https://www.youtube.com/embed/{{ id }}" | |
webkitallowfullscreen mozallowfullscreen allowfullscreen frameborder="0"></iframe></div>"#; | |
let mut partial = InMemorySource::new(); | |
partial.add("youtube_snippet", snippet); | |
let compiler = LazyCompiler::new(partial); | |
let partial = compiler.compile(Arc::new(options.clone()))?; | |
Ok(Box::new(Youtube { id, class, partial })) | |
} | |
// fn reflection(&self) -> &dyn TagReflection { | |
// self | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment