mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Wiring up the api and webassembly ui
This commit is contained in:
parent
d846e04418
commit
882615a3cd
77
Cargo.lock
generated
77
Cargo.lock
generated
@ -650,6 +650,17 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gloo-utils"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05c77af6f96a4f9e27c8ac23a88407381a31f4a74c3fb985c85aa79b8d898136"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.10"
|
version = "0.3.10"
|
||||||
@ -834,9 +845,9 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.55"
|
version = "0.3.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
@ -1255,6 +1266,26 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwasm"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34b9b71430c0b3f076a806c389b5a8f806171a1b9365692b86e9878ad1312879"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"gloo-utils",
|
||||||
|
"js-sys",
|
||||||
|
"pin-project",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.21"
|
version = "0.1.21"
|
||||||
@ -1284,6 +1315,20 @@ name = "serde"
|
|||||||
version = "1.0.130"
|
version = "1.0.130"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.130"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
@ -1711,19 +1756,21 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.78"
|
version = "0.2.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.78"
|
version = "0.2.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@ -1748,9 +1795,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.78"
|
version = "0.2.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
@ -1758,9 +1805,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.78"
|
version = "0.2.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1771,9 +1818,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.78"
|
version = "0.2.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-test"
|
name = "wasm-bindgen-test"
|
||||||
@ -1816,13 +1863,15 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"dioxus",
|
"dioxus",
|
||||||
"recipes",
|
"recipes",
|
||||||
|
"reqwasm",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.55"
|
version = "0.3.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
31
kitchen/src/api.rs
Normal file
31
kitchen/src/api.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2022 Jeremy Wall
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ParseError {
|
||||||
|
IO(std::io::Error),
|
||||||
|
Syntax(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for ParseError {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
ParseError::IO(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for ParseError {
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
ParseError::Syntax(s)
|
||||||
|
}
|
||||||
|
}
|
@ -19,14 +19,9 @@ use std::path::Path;
|
|||||||
|
|
||||||
use csv;
|
use csv;
|
||||||
|
|
||||||
|
use crate::api::ParseError;
|
||||||
use recipes::{parse, IngredientAccumulator, Recipe};
|
use recipes::{parse, IngredientAccumulator, Recipe};
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum ParseError {
|
|
||||||
IO(std::io::Error),
|
|
||||||
Syntax(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(jwall): We should think a little more closely about
|
// TODO(jwall): We should think a little more closely about
|
||||||
// the error modeling for this application.
|
// the error modeling for this application.
|
||||||
macro_rules! try_open {
|
macro_rules! try_open {
|
||||||
@ -41,18 +36,6 @@ macro_rules! try_open {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for ParseError {
|
|
||||||
fn from(err: std::io::Error) -> Self {
|
|
||||||
ParseError::IO(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for ParseError {
|
|
||||||
fn from(s: String) -> Self {
|
|
||||||
ParseError::Syntax(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_recipe<P>(path: P) -> Result<Recipe, ParseError>
|
pub fn parse_recipe<P>(path: P) -> Result<Recipe, ParseError>
|
||||||
where
|
where
|
||||||
P: AsRef<Path> + Debug,
|
P: AsRef<Path> + Debug,
|
||||||
|
@ -11,14 +11,16 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
mod cli;
|
|
||||||
mod web;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap;
|
use clap;
|
||||||
use clap::{clap_app, crate_authors, crate_version};
|
use clap::{clap_app, crate_authors, crate_version};
|
||||||
|
|
||||||
|
pub mod api;
|
||||||
|
mod cli;
|
||||||
|
mod web;
|
||||||
|
|
||||||
fn create_app<'a, 'b>() -> clap::App<'a, 'b>
|
fn create_app<'a, 'b>() -> clap::App<'a, 'b>
|
||||||
where
|
where
|
||||||
'a: 'b,
|
'a: 'b,
|
||||||
@ -39,6 +41,7 @@ where
|
|||||||
)
|
)
|
||||||
(@subcommand serve =>
|
(@subcommand serve =>
|
||||||
(about: "Serve the interface via the web")
|
(about: "Serve the interface via the web")
|
||||||
|
(@arg recipe_dir: -d --dir +takes_value "Directory containing recipe files to use")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
|
.setting(clap::AppSettings::SubcommandRequiredElseHelp)
|
||||||
@ -72,8 +75,13 @@ fn main() {
|
|||||||
eprintln!("{:?}", e);
|
eprintln!("{:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if matches.subcommand_matches("serve").is_some() {
|
} else if let Some(matches) = matches.subcommand_matches("serve") {
|
||||||
println!("Launching web interface...");
|
println!("Launching web interface...");
|
||||||
async_std::task::block_on(async { web::ui_main().await });
|
let recipe_dir_path = if let Some(dir) = matches.value_of("recipe_dir") {
|
||||||
|
PathBuf::from(dir)
|
||||||
|
} else {
|
||||||
|
std::env::current_dir().expect("Unable to get current directory. Bailing out.")
|
||||||
|
};
|
||||||
|
async_std::task::block_on(async { web::ui_main(recipe_dir_path).await });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,16 +11,53 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use static_dir::static_dir;
|
use std::path::PathBuf;
|
||||||
use warp::{hyper::Uri, Filter};
|
|
||||||
|
|
||||||
pub async fn ui_main() {
|
use async_std::fs::{read_dir, read_to_string, DirEntry};
|
||||||
|
use async_std::stream::StreamExt;
|
||||||
|
use static_dir::static_dir;
|
||||||
|
use warp::{http::StatusCode, hyper::Uri, Filter};
|
||||||
|
|
||||||
|
use crate::api::ParseError;
|
||||||
|
|
||||||
|
pub async fn get_recipes(recipe_dir_path: PathBuf) -> Result<Vec<String>, ParseError> {
|
||||||
|
let mut entries = read_dir(recipe_dir_path).await?;
|
||||||
|
let mut entry_vec = Vec::new();
|
||||||
|
while let Some(res) = entries.next().await {
|
||||||
|
let entry: DirEntry = res?;
|
||||||
|
if entry.file_type().await?.is_dir() || entry.file_name().to_string_lossy() != "menu.txt" {
|
||||||
|
// add it to the entry
|
||||||
|
let recipe_contents = read_to_string(entry.path()).await?;
|
||||||
|
entry_vec.push(recipe_contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(entry_vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn ui_main(recipe_dir_path: PathBuf) {
|
||||||
let root = warp::path::end().map(|| warp::redirect::found(Uri::from_static("/ui")));
|
let root = warp::path::end().map(|| warp::redirect::found(Uri::from_static("/ui")));
|
||||||
let ui = warp::path("ui").and(static_dir!("webdist/"));
|
let ui = warp::path("ui").and(static_dir!("webdist/"));
|
||||||
// api route goes here eventually.
|
// TODO(jwall): Figure out how to make and_then work to simplify the below.
|
||||||
let api = warp::path!("api" / " v1").map(|| format!("API stuff goes here!"));
|
let api = warp::path("api")
|
||||||
|
.and(warp::path("v1"))
|
||||||
|
.and(warp::path("recipes"))
|
||||||
|
.then(move || {
|
||||||
|
let recipe_dir_path = (&recipe_dir_path).clone();
|
||||||
|
eprintln!("servicing api request.");
|
||||||
|
async move {
|
||||||
|
match get_recipes(recipe_dir_path).await {
|
||||||
|
Ok(recipes) => {
|
||||||
|
warp::reply::with_status(warp::reply::json(&recipes), StatusCode::OK)
|
||||||
|
}
|
||||||
|
Err(e) => warp::reply::with_status(
|
||||||
|
warp::reply::json(&format!("Error: {:?}", e)),
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let routes = root.or(ui).or(api).boxed();
|
let routes = root.or(ui).or(api).with(warp::log("access log"));
|
||||||
|
|
||||||
// TODO(jwall): Take listen address as an argument to this function instead.
|
// TODO(jwall): Take listen address as an argument to this function instead.
|
||||||
warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
|
warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
|
||||||
|
2
run.sh
2
run.sh
@ -14,4 +14,4 @@
|
|||||||
|
|
||||||
make clean kitchen
|
make clean kitchen
|
||||||
cd kitchen
|
cd kitchen
|
||||||
cargo run -- serve
|
cargo run -- serve --dir ../examples
|
@ -7,6 +7,11 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
recipes = {path = "../recipes" }
|
recipes = {path = "../recipes" }
|
||||||
|
reqwasm = "0.4.0"
|
||||||
|
|
||||||
|
[dependencies.wasm-bindgen]
|
||||||
|
version = "0.2.79"
|
||||||
|
#features = [ "console" ]
|
||||||
|
|
||||||
[dependencies.dioxus]
|
[dependencies.dioxus]
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
mod typings;
|
||||||
mod web;
|
mod web;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
32
web/src/typings.rs
Normal file
32
web/src/typings.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2022 Jeremy Wall
|
||||||
|
//
|
||||||
|
// 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 wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern "C" {
|
||||||
|
// Use `js_namespace` here to bind `console.log(..)` instead of just
|
||||||
|
// `log(..)`
|
||||||
|
#[wasm_bindgen(js_namespace = console)]
|
||||||
|
pub fn log(s: &str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! console_log {
|
||||||
|
// Note that this is using the `log` function imported above during
|
||||||
|
// `bare_bones`
|
||||||
|
($($t:tt)*) => {{
|
||||||
|
use crate::typings::log;
|
||||||
|
(log(&format_args!($($t)*).to_string()))
|
||||||
|
}}
|
||||||
|
}
|
@ -11,10 +11,79 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
use std::iter::Iterator;
|
||||||
|
|
||||||
|
use crate::console_log;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use reqwasm::http;
|
||||||
|
|
||||||
|
use recipes::{parse, Recipe};
|
||||||
|
|
||||||
|
#[derive(Props, PartialEq)]
|
||||||
|
struct RecipeListProps {
|
||||||
|
recipe_list: Vec<Recipe>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Component to list available recipes.
|
||||||
|
fn RecipeList(cx: Scope) -> Element {
|
||||||
|
let props = use_state(&cx, || RecipeListProps {
|
||||||
|
recipe_list: vec![],
|
||||||
|
});
|
||||||
|
|
||||||
|
use_future(&cx, || {
|
||||||
|
let props = props.for_async();
|
||||||
|
async move {
|
||||||
|
let req = http::Request::get("/api/v1/recipes").send().await;
|
||||||
|
match req {
|
||||||
|
Ok(resp) => {
|
||||||
|
if resp.status() != 200 {
|
||||||
|
console_log!("Status: {}", resp.status());
|
||||||
|
} else {
|
||||||
|
console_log!("We got a valid response back!");
|
||||||
|
let recipe_list = match resp.json::<Vec<String>>().await {
|
||||||
|
Ok(recipes) => recipes,
|
||||||
|
Err(e) => {
|
||||||
|
console_log!("Eror getting recipe list as json {}", e);
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut parsed_list = Vec::new();
|
||||||
|
for r in recipe_list {
|
||||||
|
let recipe = match parse::as_recipe(&r) {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => {
|
||||||
|
console_log!("Error parsing recipe {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console_log!("We parsed a recipe {}", recipe.title);
|
||||||
|
parsed_list.push(recipe);
|
||||||
|
}
|
||||||
|
props.set(RecipeListProps {
|
||||||
|
recipe_list: parsed_list,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
console_log!("Error: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cx.render(rsx! {
|
||||||
|
ul {
|
||||||
|
(&props.recipe_list).into_iter().map(|i| {
|
||||||
|
let title = &i.title;
|
||||||
|
rsx!(li { "{title}" })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ui(cx: Scope) -> Element {
|
pub fn ui(cx: Scope) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div { "hello chefs!" }
|
div { "hello chefs!" }
|
||||||
|
RecipeList { }
|
||||||
})
|
})
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user