diff --git a/examples/session_auth_axum/.env b/examples/session_auth_axum/.env new file mode 100644 index 0000000000..6d8fc2c590 --- /dev/null +++ b/examples/session_auth_axum/.env @@ -0,0 +1 @@ +DATABASE_URL=sqlite://Todos.db diff --git a/examples/session_auth_axum/src/error_template.rs b/examples/session_auth_axum/src/error_template.rs index 329dfd7f4d..4f760c6b69 100644 --- a/examples/session_auth_axum/src/error_template.rs +++ b/examples/session_auth_axum/src/error_template.rs @@ -39,22 +39,21 @@ pub fn ErrorTemplate( } view! { -

"Errors"

- {error_code.to_string()} -

"Error: " {error_string}

- } - } - /> +

"Errors"

+ {error_code.to_string()} +

"Error: " {error_string}

+ } + } + /> } } diff --git a/examples/session_auth_axum/src/todo.rs b/examples/session_auth_axum/src/todo.rs index 104a414174..97ad08ad6f 100644 --- a/examples/session_auth_axum/src/todo.rs +++ b/examples/session_auth_axum/src/todo.rs @@ -15,70 +15,56 @@ pub struct Todo { } cfg_if! { -if #[cfg(feature = "ssr")] { + if #[cfg(feature = "ssr")] { - use sqlx::SqlitePool; + use sqlx::SqlitePool; + use futures::future::join_all; - pub fn pool() -> Result { - use_context::() - .ok_or_else(|| ServerFnError::ServerError("Pool missing.".into())) - } + pub fn pool() -> Result { + use_context::() + .ok_or_else(|| ServerFnError::ServerError("Pool missing.".into())) + } - pub fn auth() -> Result { - use_context::() - .ok_or_else(|| ServerFnError::ServerError("Auth session missing.".into())) - } + pub fn auth() -> Result { + use_context::() + .ok_or_else(|| ServerFnError::ServerError("Auth session missing.".into())) + } - #[derive(sqlx::FromRow, Clone)] - pub struct SqlTodo { - id: u32, - user_id: i64, - title: String, - created_at: String, - completed: bool, - } + #[derive(sqlx::FromRow, Clone)] + pub struct SqlTodo { + id: u32, + user_id: i64, + title: String, + created_at: String, + completed: bool, + } - impl SqlTodo { - pub async fn into_todo(self, pool: &SqlitePool) -> Todo { - Todo { - id: self.id, - user: User::get(self.user_id, pool).await, - title: self.title, - created_at: self.created_at, - completed: self.completed, + impl SqlTodo { + pub async fn into_todo(self, pool: &SqlitePool) -> Todo { + Todo { + id: self.id, + user: User::get(self.user_id, pool).await, + title: self.title, + created_at: self.created_at, + completed: self.completed, + } } } } } -} #[server(GetTodos, "/api")] pub async fn get_todos() -> Result, ServerFnError> { - use futures::TryStreamExt; - let pool = pool()?; - let mut todos = Vec::new(); - let mut rows = - sqlx::query_as::<_, SqlTodo>("SELECT * FROM todos").fetch(&pool); - - while let Some(row) = rows.try_next().await? { - todos.push(row); - } - - // why can't we just have async closures? - // let mut rows: Vec = rows.iter().map(|t| async { t }).collect(); - - let mut converted_todos = Vec::with_capacity(todos.len()); - - for t in todos { - let todo = t.into_todo(&pool).await; - converted_todos.push(todo); - } - - let todos: Vec = converted_todos; - - Ok(todos) + Ok(join_all( + sqlx::query_as::<_, SqlTodo>("SELECT * FROM todos") + .fetch_all(&pool) + .await? + .iter() + .map(|todo: &SqlTodo| todo.clone().into_todo(&pool)), + ) + .await) } #[server(AddTodo, "/api")] @@ -94,17 +80,14 @@ pub async fn add_todo(title: String) -> Result<(), ServerFnError> { // fake API delay std::thread::sleep(std::time::Duration::from_millis(1250)); - match sqlx::query( + Ok(sqlx::query( "INSERT INTO todos (title, user_id, completed) VALUES (?, ?, false)", ) .bind(title) .bind(id) .execute(&pool) .await - { - Ok(_row) => Ok(()), - Err(e) => Err(ServerFnError::ServerError(e.to_string())), - } + .map(|_| ())?) } // The struct name and path prefix arguments are optional. @@ -138,51 +121,71 @@ pub fn TodoApp() -> impl IntoView { provide_meta_context(); view! { -
-

"My Tasks"

- "Loading..."} - > - {move || { - user.get().map(|user| match user { - Err(e) => view! { - "Signup"", " - "Login"", " - {format!("Login error: {}", e)} - }.into_view(), - Ok(None) => view! { - "Signup"", " - "Login"", " - "Logged out." - }.into_view(), - Ok(Some(user)) => view! { - "Settings"", " - {format!("Logged in as: {} ({})", user.username, user.id)} - }.into_view() - }) - }} + +

"My Tasks"

+
+ "Loading..." } + }> + {move || { + user.get() + .map(|user| match user { + Err(e) => { + view! { + "Signup" + ", " + "Login" + ", " + {format!("Login error: {}", e)} + } + .into_view() + } + Ok(None) => { + view! { + "Signup" + ", " + "Login" + ", " + "Logged out." + } + .into_view() + } + Ok(Some(user)) => { + view! { + "Settings" + ", " + + {format!("Logged in as: {} ({})", user.username, user.id)} + + } + .into_view() + } + }) + }} +

- //Route - - }/> - - }/> - + }/> + }/> + "Settings" + + } + } + /> -

"Settings"

- - }/>
@@ -202,24 +205,26 @@ pub fn Todos() -> impl IntoView { ); view! { -
- + - "Loading..."

}> - }> + "Loading..."

}> + } + }> {move || { let existing_todos = { move || { - todos.get() + todos + .get() .map(move |todos| match todos { Err(e) => { - view! {
"Server Error: " {e.to_string()}
}.into_view() + view! { +
"Server Error: " {e.to_string()}
+ } + .into_view() } Ok(todos) => { if todos.is_empty() { @@ -229,17 +234,11 @@ pub fn Todos() -> impl IntoView { .into_iter() .map(move |todo| { view! { -
  • - {todo.title} - ": Created at " - {todo.created_at} - " by " - { - todo.user.unwrap_or_default().username - } + {todo.title} ": Created at " {todo.created_at} " by " + {todo.user.unwrap_or_default().username} - +
  • @@ -252,30 +251,23 @@ pub fn Todos() -> impl IntoView { .unwrap_or_default() } }; - let pending_todos = move || { submissions - .get() - .into_iter() - .filter(|submission| submission.pending().get()) - .map(|submission| { - view! { - -
  • {move || submission.input.get().map(|data| data.title) }
  • - } - }) - .collect_view() + .get() + .into_iter() + .filter(|submission| submission.pending().get()) + .map(|submission| { + view! { +
  • + {move || submission.input.get().map(|data| data.title)} +
  • + } + }) + .collect_view() }; + view! {
      {existing_todos} {pending_todos}
    } + }} - view! { - -
      - {existing_todos} - {pending_todos} -
    - } - } - }
    @@ -287,25 +279,32 @@ pub fn Login( action: Action>, ) -> impl IntoView { view! { -

    "Log In"




    - +
    } } @@ -315,31 +314,42 @@ pub fn Signup( action: Action>, ) -> impl IntoView { view! { -

    "Sign Up"





    - +
    } } @@ -349,10 +359,11 @@ pub fn Logout( action: Action>, ) -> impl IntoView { view! { -
    - +
    }