"]
6 | publish = false
7 |
8 | [[bin]]
9 | name = "example_staticfiles"
10 | path = "src/main.rs"
11 | doc = false
12 |
13 | [dependencies]
14 | finchers = "0.13"
15 |
--------------------------------------------------------------------------------
/examples/staticfiles/src/main.rs:
--------------------------------------------------------------------------------
1 | use finchers::prelude::*;
2 | use finchers::{path, routes};
3 |
4 | fn main() {
5 | let endpoint = routes![
6 | path!(@get /).and(endpoints::fs::file("./Cargo.toml")),
7 | path!(@get / "public").and(endpoints::fs::dir("./static")),
8 | endpoint::syntax::verb::get().map(|| "Not found"),
9 | ];
10 |
11 | finchers::server::start(endpoint)
12 | .serve("127.0.0.1:5000")
13 | .unwrap_or_else(|e| eprintln!("{}", e));
14 | }
15 |
--------------------------------------------------------------------------------
/examples/staticfiles/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Index
7 |
8 |
9 |
10 | Finchers
11 |
12 | Finchers is a Rust Web framework focuses on asynchronous and type-safe handling.
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/template-askama/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "example-template-askama"
3 | version = "0.0.0"
4 | authors = ["Yusuke Sasaki "]
5 | publish = false
6 |
7 | build = "build.rs"
8 |
9 | [[bin]]
10 | name = "example_template_askama"
11 | path = "src/main.rs"
12 | doc = false
13 |
14 | [dependencies]
15 | finchers = "0.13"
16 | finchers-template = { version = "0.2.0-dev", features = ["use-askama"] }
17 | askama = "0.7"
18 | pretty_env_logger = "0.2.4"
19 | log = "0.4.5"
20 |
21 | [build-dependencies]
22 | askama = "0.7"
23 |
--------------------------------------------------------------------------------
/examples/template-askama/build.rs:
--------------------------------------------------------------------------------
1 | extern crate askama;
2 |
3 | fn main() {
4 | askama::rerun_if_templates_changed();
5 | }
6 |
--------------------------------------------------------------------------------
/examples/template-askama/src/main.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate askama;
3 | #[macro_use]
4 | extern crate finchers;
5 | extern crate finchers_template;
6 | #[macro_use]
7 | extern crate log;
8 | extern crate pretty_env_logger;
9 |
10 | use finchers::prelude::*;
11 |
12 | use askama::Template;
13 |
14 | #[derive(Debug, Template)]
15 | #[template(path = "index.html")]
16 | struct UserInfo {
17 | name: String,
18 | }
19 |
20 | fn main() {
21 | std::env::set_var("RUST_LOG", "example_askama=info");
22 | pretty_env_logger::init();
23 |
24 | let endpoint = path!(@get /)
25 | .map(|| UserInfo {
26 | name: "Alice".into(),
27 | })
28 | .wrap(finchers_template::askama());
29 |
30 | info!("Listening on http://127.0.0.1:4000");
31 | finchers::server::start(endpoint)
32 | .serve("127.0.0.1:4000")
33 | .unwrap_or_else(|e| error!("{}", e));
34 | }
35 |
--------------------------------------------------------------------------------
/examples/template-askama/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Greeting
6 |
7 |
8 | Hello, {{ name }}.
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/template-handlebars/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "example-template-handlebars"
3 | version = "0.0.0"
4 | authors = ["Yusuke Sasaki "]
5 | publish = false
6 |
7 | [[bin]]
8 | name = "example_template_handlebars"
9 | path = "src/main.rs"
10 | doc = false
11 |
12 | [dependencies]
13 | finchers = "0.13"
14 | finchers-template = { version = "0.2.0-dev", features = ["use-handlebars"] }
15 | handlebars = "1"
16 | pretty_env_logger = "0.2.4"
17 | log = "0.4.5"
18 | serde = "1"
19 |
--------------------------------------------------------------------------------
/examples/template-handlebars/src/main.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate finchers;
3 | extern crate finchers_template;
4 | #[macro_use]
5 | extern crate log;
6 | extern crate pretty_env_logger;
7 | #[macro_use]
8 | extern crate serde;
9 | extern crate handlebars;
10 |
11 | use finchers::prelude::*;
12 |
13 | use handlebars::Handlebars;
14 |
15 | #[derive(Debug, Serialize)]
16 | struct UserInfo {
17 | name: String,
18 | }
19 |
20 | impl UserInfo {
21 | const TEMPLATE_NAME: &'static str = "index.html";
22 |
23 | const TEMPLATE_STR: &'static str = "\
24 |
25 |
26 |
27 |
28 | Greeting
29 |
30 |
31 | Hello, {{ name }}.
32 |
33 | ";
34 | }
35 |
36 | fn main() {
37 | pretty_env_logger::init();
38 |
39 | let mut engine = Handlebars::new();
40 | engine
41 | .register_template_string(UserInfo::TEMPLATE_NAME, UserInfo::TEMPLATE_STR)
42 | .unwrap();
43 |
44 | let endpoint = path!(@get /)
45 | .map(|| UserInfo {
46 | name: "Alice".into(),
47 | })
48 | .wrap(finchers_template::handlebars(
49 | engine,
50 | UserInfo::TEMPLATE_NAME,
51 | ));
52 |
53 | info!("Listening on http://127.0.0.1:4000");
54 | finchers::server::start(endpoint)
55 | .serve("127.0.0.1:4000")
56 | .unwrap_or_else(|e| error!("{}", e));
57 | }
58 |
--------------------------------------------------------------------------------
/examples/template-horrorshow/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "example-template-horrorshow"
3 | version = "0.0.0"
4 | authors = ["Yusuke Sasaki "]
5 | publish = false
6 |
7 | [[bin]]
8 | name = "example_template_horrorshow"
9 | path = "src/main.rs"
10 | doc = false
11 |
12 | [dependencies]
13 | finchers = "0.13"
14 | finchers-template = { version = "0.2.0-dev", features = ["use-horrorshow"] }
15 | horrorshow = "0.6"
16 | pretty_env_logger = "0.2.4"
17 | log = "0.4.5"
18 |
--------------------------------------------------------------------------------
/examples/template-horrorshow/src/main.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate finchers;
3 | extern crate finchers_template;
4 | #[macro_use]
5 | extern crate log;
6 | extern crate pretty_env_logger;
7 | #[macro_use]
8 | extern crate horrorshow;
9 |
10 | use finchers::prelude::*;
11 |
12 | use horrorshow::helper::doctype;
13 |
14 | fn main() {
15 | std::env::set_var("RUST_LOG", "horrorshow=info");
16 | pretty_env_logger::init();
17 |
18 | let endpoint = path!(@get /)
19 | .map(|| {
20 | html! {
21 | : doctype::HTML;
22 | html {
23 | head {
24 | meta(charset="utf-8");
25 | title: "Greeting";
26 | }
27 | body {
28 | p: format!("Hello, {}", "Alice");
29 | }
30 | }
31 | }
32 | })
33 | .wrap(finchers_template::horrorshow());
34 |
35 | info!("Listening on http://127.0.0.1:4000");
36 | finchers::server::start(endpoint)
37 | .serve("127.0.0.1:4000")
38 | .unwrap_or_else(|e| error!("{}", e));
39 | }
40 |
--------------------------------------------------------------------------------
/examples/template-tera/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "example-template-tera"
3 | version = "0.0.0"
4 | authors = ["Yusuke Sasaki "]
5 | publish = false
6 |
7 | [[bin]]
8 | name = "example_template_tera"
9 | path = "src/main.rs"
10 | doc = false
11 |
12 | [dependencies]
13 | finchers = "0.13"
14 | finchers-template = { version = "0.2.0-dev", features = ["use-tera"] }
15 | tera = "0.11"
16 | pretty_env_logger = "0.2.4"
17 | log = "0.4.5"
18 | serde = "1"
19 |
--------------------------------------------------------------------------------
/examples/template-tera/src/main.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate finchers;
3 | extern crate finchers_template;
4 | #[macro_use]
5 | extern crate log;
6 | extern crate pretty_env_logger;
7 | #[macro_use]
8 | extern crate serde;
9 | extern crate tera;
10 |
11 | use finchers::prelude::*;
12 |
13 | use tera::Tera;
14 |
15 | #[derive(Debug, Serialize)]
16 | struct UserInfo {
17 | name: String,
18 | }
19 |
20 | impl UserInfo {
21 | const TEMPLATE_NAME: &'static str = "index.html";
22 |
23 | const TEMPLATE_STR: &'static str = "\
24 |
25 |
26 |
27 |
28 | Greeting
29 |
30 |
31 | Hello, {{ name }}.
32 |
33 | ";
34 | }
35 |
36 | fn main() {
37 | pretty_env_logger::init();
38 |
39 | let mut engine = Tera::default();
40 | engine
41 | .add_raw_template(UserInfo::TEMPLATE_NAME, UserInfo::TEMPLATE_STR)
42 | .unwrap();
43 |
44 | let endpoint = {
45 | path!(@get /)
46 | .map(|| UserInfo {
47 | name: "Alice".into(),
48 | })
49 | .wrap(finchers_template::tera(engine, UserInfo::TEMPLATE_NAME))
50 | };
51 |
52 | info!("Listening on http://127.0.0.1:4000");
53 | finchers::server::start(endpoint)
54 | .serve("127.0.0.1:4000")
55 | .unwrap_or_else(|e| error!("{}", e));
56 | }
57 |
--------------------------------------------------------------------------------
/examples/websocket/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "example-websocket"
3 | version = "0.0.0"
4 | authors = ["Yusuke Sasaki "]
5 | edition = "2018"
6 |
7 | [[bin]]
8 | name = "example_websocket"
9 | path = "src/main.rs"
10 | doc = false
11 |
12 | [dependencies]
13 | finchers = "0.13"
14 | finchers-tungstenite = "0.2"
15 |
16 | futures = "0.1.24"
17 | http = "0.1.13"
18 | pretty_env_logger = "0.2.4"
19 | log = "0.4.5"
20 | tungstenite = "0.6.0"
21 |
--------------------------------------------------------------------------------
/examples/websocket/src/main.rs:
--------------------------------------------------------------------------------
1 | use finchers::prelude::*;
2 | use futures::prelude::*;
3 | use http::Response;
4 |
5 | use finchers_tungstenite::{ws, Ws, WsTransport};
6 | use tungstenite::error::Error as WsError;
7 | use tungstenite::Message;
8 |
9 | fn on_upgrade(stream: WsTransport) -> impl Future- {
10 | let (tx, rx) = stream.split();
11 | rx.filter_map(|m| {
12 | log::info!("Message from client: {:?}", m);
13 | match m {
14 | Message::Ping(p) => Some(Message::Pong(p)),
15 | Message::Pong(..) => None,
16 | m => Some(m),
17 | }
18 | })
19 | .forward(tx)
20 | .map(|_| ())
21 | .map_err(|e| match e {
22 | WsError::ConnectionClosed(..) => log::info!("connection is closed"),
23 | e => log::error!("error during handling WebSocket connection: {}", e),
24 | })
25 | }
26 |
27 | fn main() {
28 | pretty_env_logger::init();
29 |
30 | let index = finchers::path!(/).map(|| {
31 | Response::builder()
32 | .header("content-type", "text/html; charset=utf-8")
33 | .body(
34 | r#"
35 |
36 |
37 |
38 | Index
39 |
40 |
41 |
42 |
43 | "#,
44 | )
45 | .unwrap()
46 | });
47 |
48 | let ws_endpoint = finchers::path!(/ "ws" /).and(ws()).map(|ws: Ws| {
49 | log::info!("accepted a WebSocket request");
50 | ws.on_upgrade(on_upgrade)
51 | });
52 |
53 | let endpoint = index.or(ws_endpoint);
54 |
55 | log::info!("Listening on http://127.0.0.1:4000");
56 | finchers::server::start(endpoint)
57 | .serve("127.0.0.1:4000")
58 | .unwrap_or_else(|e| log::error!("{}", e));
59 | }
60 |
--------------------------------------------------------------------------------
/finchers-juniper/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "finchers-juniper"
3 | version = "0.2.1"
4 | authors = ["Yusuke Sasaki "]
5 | description = """
6 | A set of extensions for supporting Juniper integration.
7 | """
8 | license = "MIT OR Apache-2.0"
9 | readme = "README.md"
10 | repository = "https://github.com/finchers-rs/finchers-juniper.git"
11 |
12 | include = [
13 | "Cargo.toml",
14 | "build.rs",
15 | "src/**/*",
16 | "tests/**/*",
17 | "examples/**/*",
18 | "benches/**/*",
19 | "LICENSE-MIT",
20 | "LICENSE-APACHE",
21 | "README.md"
22 | ]
23 |
24 | [package.metadata.docs.rs]
25 | # FIXME: remove it as soon as the rustc version used in docs.rs is updated
26 | rustdoc-args = ["--cfg", "finchers_inject_extern_prelude"]
27 |
28 | [dependencies]
29 | finchers = "0.13"
30 |
31 | bytes = "0.4.9"
32 | failure = { version = "0.1.2", features = ["derive"] }
33 | futures = "0.1.24"
34 | http = "0.1.10"
35 | juniper = "0.10.0"
36 | log = "0.4.5"
37 | percent-encoding = "1.0.1"
38 | serde = { version = "1.0.75", features = ["derive"] }
39 | serde_json = "1.0.26"
40 | serde_qs = "0.4.1"
41 |
42 | [dev-dependencies]
43 | pretty_env_logger = "0.2.4"
44 | juniper = { version = "0.10.0", features = ["expose-test-schema", "serde_json"] }
45 | futures-cpupool = "0.1.8"
46 | matches = "0.1.8"
47 | cargo-husky = "1.0.1"
48 |
--------------------------------------------------------------------------------
/finchers-juniper/README.md:
--------------------------------------------------------------------------------
1 | # `finchers-juniper`
2 |
3 | [](https://crates.io/crates/finchers-juniper)
4 | [](https://docs.rs/finchers-juniper)
5 | [](https://deps.rs/crate/finchers-juniper/0.2.1)
6 | [](https://travis-ci.org/finchers-rs/finchers-juniper)
7 | [](https://coveralls.io/github/finchers-rs/finchers-juniper?branch=master)
8 |
9 | A set of extensions for integrating [Juniper] endpoints.
10 |
11 | [Juniper]: https://github.com/graphql-rust/juniper
12 |
13 | ## License
14 |
15 | [MIT license](../LICENSE-MIT) or [Apache License, Version 2.0](../LICENSE-APACHE) at your option.
16 |
--------------------------------------------------------------------------------
/finchers-juniper/changelog.md:
--------------------------------------------------------------------------------
1 |
2 | ### 0.2.1 (2018-10-15)
3 |
4 | * fix badge URL in README.md
5 |
6 |
7 | ## 0.2.0 (2018-10-09)
8 |
9 | The initial release on this iteration.
10 |
11 | * bump `finchers` to `0.13`
12 | * introduce the trait `Schema` and `SharedSchema` for abstraction of `RootNode`
13 | - The advantages in here are as follows:
14 | + Simplify the trait bounds in GraphQL executors
15 | + `Box`, `Rc` and `Arc` implements `Schema`
16 |
17 |
18 | ### 0.1.1 (2018-10-02)
19 | * update metadata in Cargo.toml
20 |
21 |
22 | ## 0.1.0 (2018-09-30)
23 | The initial release on this iteration.
24 |
--------------------------------------------------------------------------------
/finchers-juniper/examples/executors.rs:
--------------------------------------------------------------------------------
1 | extern crate finchers;
2 | extern crate finchers_juniper;
3 | extern crate futures; // 0.1
4 | extern crate futures_cpupool;
5 | #[macro_use]
6 | extern crate juniper;
7 | #[macro_use]
8 | extern crate log;
9 | extern crate pretty_env_logger;
10 |
11 | use finchers::endpoint::syntax;
12 | use finchers::prelude::*;
13 | use finchers_juniper::execute;
14 |
15 | use futures_cpupool::CpuPool;
16 | use juniper::{EmptyMutation, RootNode};
17 | use std::sync::Arc;
18 |
19 | struct MyContext {
20 | _priv: (),
21 | }
22 |
23 | impl juniper::Context for MyContext {}
24 |
25 | struct Query;
26 |
27 | graphql_object!(Query: MyContext |&self| {
28 | field apiVersion() -> &str {
29 | "1.0"
30 | }
31 | });
32 |
33 | fn main() {
34 | pretty_env_logger::init();
35 |
36 | let schema = Arc::new(RootNode::new(Query, EmptyMutation::::new()));
37 |
38 | let current_thread_endpoint = syntax::segment("current")
39 | .map(|| MyContext { _priv: () })
40 | .wrap(execute::current_thread(schema.clone()));
41 |
42 | let nonblocking_endpoint = syntax::segment("nonblocking")
43 | .map(|| MyContext { _priv: () })
44 | .wrap(execute::nonblocking(schema.clone()));
45 |
46 | let cpupool_endpoint = syntax::segment("cpupool")
47 | .map(|| MyContext { _priv: () })
48 | .wrap(execute::with_spawner(
49 | schema.clone(),
50 | CpuPool::new_num_cpus(),
51 | ));
52 |
53 | let endpoint = current_thread_endpoint
54 | .or(nonblocking_endpoint)
55 | .or(cpupool_endpoint);
56 |
57 | info!("Listening on http://127.0.0.1:4000/");
58 | finchers::server::start(endpoint)
59 | .serve("127.0.0.1:4000")
60 | .unwrap_or_else(|err| error!("{}", err));
61 | }
62 |
--------------------------------------------------------------------------------
/finchers-juniper/examples/todos.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate failure;
3 | #[macro_use]
4 | extern crate finchers;
5 | extern crate finchers_juniper;
6 | #[macro_use]
7 | extern crate juniper;
8 | #[macro_use]
9 | extern crate log;
10 | extern crate pretty_env_logger;
11 |
12 | use finchers::prelude::*;
13 |
14 | use failure::Fallible;
15 | use std::sync::Arc;
16 |
17 | use business::Repository;
18 | use graphql::{create_schema, Context};
19 |
20 | fn main() -> Fallible<()> {
21 | pretty_env_logger::try_init()?;
22 |
23 | let repository = Arc::new(Repository::init());
24 | let context_endpoint = endpoint::cloned(repository).map(|repository| Context { repository });
25 |
26 | let graphql_endpoint = path!(/ "graphql" /)
27 | .and(context_endpoint)
28 | .wrap(finchers_juniper::execute::nonblocking(create_schema()));
29 |
30 | let graphiql_endpoint = path!(@get /).and(finchers_juniper::graphiql_source("/graphql"));
31 |
32 | let endpoint = graphql_endpoint.or(graphiql_endpoint);
33 |
34 | info!("Listening on http://127.0.0.1:4000");
35 | finchers::server::start(endpoint)
36 | .serve("127.0.0.1:4000")
37 | .map_err(Into::into)
38 | }
39 |
40 | /// The implelentation of business logic.
41 | mod business {
42 | use failure::Fallible;
43 | use std::collections::HashMap;
44 | use std::sync::RwLock;
45 |
46 | #[derive(Debug, Clone)]
47 | pub struct Todo {
48 | pub id: i32,
49 | pub title: String,
50 | pub text: String,
51 | pub published: bool,
52 | }
53 |
54 | #[derive(Debug)]
55 | pub struct Repository(RwLock);
56 |
57 | #[derive(Debug)]
58 | struct Inner {
59 | todos: HashMap,
60 | counter: i32,
61 | }
62 |
63 | impl Repository {
64 | pub fn init() -> Repository {
65 | Repository(RwLock::new(Inner {
66 | todos: HashMap::new(),
67 | counter: 0,
68 | }))
69 | }
70 |
71 | pub fn all_todos(&self) -> Fallible> {
72 | let inner = self.0.read().map_err(|e| format_err!("{}", e))?;
73 | Ok(inner.todos.values().cloned().collect())
74 | }
75 |
76 | pub fn find_todo_by_id(&self, id: i32) -> Fallible