/* Soda by Tyler Clarke Soda is a convenient frontend framework... written in backend rust. It allows you to turn a complicated webpage design into a single server-side executable that runs on any Linux system. A core element of soda's philosophy is the idea of staying fully static: this allows the optimizing compiler to reduce potentially thousands of lines of frontend code to a few dozen inlined socket writes, which is *enormously* fast. Soda provides a set of powerful dynamic features atop the static rendering ones as well. Soda is built atop Hyper, the fastest correct HTTP server implementation in rust. */ pub mod compose; pub mod output; pub mod html; pub mod tuples; pub mod router; pub mod prelude; pub mod server; #[cfg(test)] mod tests { use super::prelude::*; #[test] fn render_composer() { // simplest example: renders a composer with DummyOutput let page = PageBase ( "Test Webpage", Tag::Paragraph("Hello, World!") ); let mut output = output::DummyOutput::new(); page.render(&mut output, &mut ()); assert_eq!(output.spool(), r#"Test Webpage

Hello, World!

"#); } #[test] fn routing_test() { fn template(content : impl Compose) -> impl Compose { PageBase ( "My Webpage", Tag::Div(( Tag::Heading1("My Test Website"), content )) ) } let page1 = template("this is the first page"); let page2 = template("this is the second page"); let page3 = template("this is the third page"); let app = page1.route_at("page1") // route GET /page1 .or(page2.route_at("page2")) // route GET /page2 .or(router::route("page_num").then(page3.route_at("3"))); // route GET /page_num/3 let mut output = output::DummyOutput::new(); app.get("https://web.app/page1").unwrap().render(&mut output, &mut ()); assert_eq!(output.spool(), r#"My Webpage

My Test Website

this is the first page
"#); output = output::DummyOutput::new(); app.get("https://web.app/page2").unwrap().render(&mut output, &mut ()); assert_eq!(output.spool(), r#"My Webpage

My Test Website

this is the second page
"#); output = output::DummyOutput::new(); app.get("https://web.app/page_num/3").unwrap().render(&mut output, &mut ()); assert_eq!(output.spool(), r#"My Webpage

My Test Website

this is the third page
"#); } #[test] fn closure_test() { // you can use embedded blocks to procedurally generate outputs let app = Tag::Div(("Hello, ", { "World!" })); let mut output = output::DummyOutput::new(); app.render(&mut output, &mut ()); assert_eq!(output.spool(), r#"
Hello, World!
"#); } #[test] fn dynamic_globalstate_test() { // composers must always be immutable. however, you can produce dynamic mutable behavior with State // it's literally just a generic of Component // you can pass pretty much whatever you want in there. let app_with_state = ( "this page has been visited ", |state : &mut u32 | { *state += 1; state.to_string() }, " times." ); let mut state : u32 = 0; for x in 0..5 { let mut output = output::DummyOutput::new(); app_with_state.render(&mut output, &mut state); assert_eq!(output.spool(), format!("this page has been visited {} times.", x + 1)); } } }