drteeth 0.1.0

Low-complexity web technology user interface library for desktop apps
// Copyright 2022 Daniel Arbuckle
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::{Arc, Mutex};

use trillium::{Conn, KnownHeaderName};
use trillium_router::Router;

struct State {
    shutdown: trillium_smol::Stopper,
}

async fn index(conn: Conn) -> Conn {
    conn.with_header(KnownHeaderName::ContentType, "text/html; charset=utf=8").ok(r#"Hello World. <form method="post" action="/shutdown"><input type="submit" value="Shut Down"></form>"#).halt()
}

async fn shutdown(conn: Conn) -> Conn {
    conn.state::<Arc<Mutex<State>>>()
        .unwrap()
        .lock()
        .unwrap()
        .shutdown
        .stop();
    conn.ok("Shutting down")
}

fn main() {
    // Non-async set up. We can do any server configuration that
    // doesn't need an async context here, parse the command line,
    // etc.

    let stopper = trillium_smol::Stopper::new();

    let state = Arc::new(Mutex::new(State {
        shutdown: stopper.clone(),
    }));

    let app = Router::new()
        .get("/", index)
        .post("/shutdown", (trillium::state(state), shutdown));

    // At the time of writing, Trillium doesn't support initialization
    // with a TcpListener, nor does it provide a way to retrieve the
    // TcpListener it's going to use, so if we ask it to allocate a
    // random port we have no way of finding out which port was
    // selected. Here's how to set it up using a consistent port
    // number instead.

    let config = trillium_smol::config()
        .with_stopper(stopper)
        .with_host("127.0.0.1")
        .with_port(8080);

    // Here we start up the webview and actually run the server. The
    // async block is the asynchronous entry point for the program
    // (like tokio::main or async_std::main), so any server set up
    // code that needs to run in an async context should be there, as
    // well as the code to actually run the server. When the async
    // block finishes executing, the program will close.

    drteeth::launch("Trillium Demo", "http://127.0.0.1:8080/", async move {
        config.run_async(app).await;
    })
    .unwrap();
}