"Error: " {error_string}
70 | } 71 | } 72 | /> 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /example/start-axum/src/fileserv.rs: -------------------------------------------------------------------------------- 1 | use cfg_if::cfg_if; 2 | 3 | cfg_if! { if #[cfg(feature = "ssr")] { 4 | use axum::{ 5 | body::{Body}, 6 | extract::State, 7 | response::IntoResponse, 8 | http::{Request, Response, StatusCode, Uri}, 9 | }; 10 | use axum::response::Response as AxumResponse; 11 | use tower::ServiceExt; 12 | use tower_http::services::fs::{ServeDir, ServeFileSystemResponseBody}; 13 | use leptos::*; 14 | use crate::app::App; 15 | 16 | pub async fn file_and_error_handler(uri: Uri, State(options): State(
151 | config: CachedImageOption,
152 | source_path: P,
153 | save_path: P,
154 | ) -> Result<(), CreateImageError>
155 | where
156 | P: AsRef (source_path: P, blur: Blur) -> Result (path: P) -> bool
364 | where
365 | P: AsRef (path: P) -> std::io::Result<()>
372 | where
373 | P: AsRef
16 | where
17 | S: Clone + Send + Sync + 'static,
18 | {
19 | /// Adds a route to the app for serving cached images.
20 | /// Requires an axum State that contains the optimizer [`crate::ImageOptimizer`].
21 | ///
22 | /// ```
23 | /// use leptos_image::*;
24 | /// use leptos::*;
25 | /// use axum::*;
26 | /// use axum::routing::post;
27 | /// use leptos_axum::{generate_route_list, handle_server_fns, LeptosRoutes};
28 | ///
29 | /// #[cfg(feature = "ssr")]
30 | /// async fn your_main_function() {
31 | ///
32 | /// let options = get_configuration(None).await.unwrap().leptos_options;
33 | /// let optimizer = ImageOptimizer::new("/__cache/image", options.site_root.clone(), 1);
34 | /// let state = AppState {leptos_options: options, optimizer: optimizer.clone() };
35 | /// let routes = generate_route_list(App);
36 | ///
37 | /// let router: Router<()> = Router::new()
38 | /// .route("/api/*fn_name", post(leptos_axum::handle_server_fns))
39 | /// // Add a handler for serving the cached images.
40 | /// .image_cache_route(&state)
41 | /// .leptos_routes_with_context(&state, routes, optimizer.provide_context(), App)
42 | /// .with_state(state);
43 | ///
44 | /// // Rest of your function ...
45 | /// }
46 | ///
47 | /// // Composite App State with the optimizer and leptos options.
48 | /// #[derive(Clone, axum::extract::FromRef)]
49 | /// struct AppState {
50 | /// leptos_options: leptos::LeptosOptions,
51 | /// optimizer: leptos_image::ImageOptimizer,
52 | /// }
53 | ///
54 | /// #[component]
55 | /// fn App() -> impl IntoView {
56 | /// provide_image_context();
57 | /// ()
58 | /// }
59 | ///
60 | /// ```
61 | ///
62 | ///
63 | fn image_cache_route(self, state: &S) -> Self;
64 | }
65 |
66 | impl ImageCacheRoute for axum::Router
67 | where
68 | S: Clone + Send + Sync + 'static,
69 | ImageOptimizer: FromRef,
70 | {
71 | fn image_cache_route(self, state: &S) -> Self {
72 | let optimizer = ImageOptimizer::from_ref(state);
73 |
74 | let path = optimizer.api_handler_path.clone();
75 | let handler = move |req: Request| image_cache_handler_inner(optimizer, req);
76 |
77 | self.route(&path, axum::routing::get(handler))
78 | }
79 | }
80 |
81 | async fn image_cache_handler_inner(optimizer: ImageOptimizer, req: Request) -> AxumResponse {
82 | let root = optimizer.root_file_path.clone();
83 | let cache_result = check_cache_image(&optimizer, req.uri().clone()).await;
84 |
85 | match cache_result {
86 | Ok(Some(uri)) => {
87 | let response = execute_file_handler(uri, &root).await.unwrap();
88 | response.into_response()
89 | }
90 |
91 | Ok(None) => Response::builder()
92 | .status(404)
93 | .body("Invalid Image.".to_string())
94 | .unwrap()
95 | .into_response(),
96 |
97 | Err(e) => {
98 | tracing::error!("Failed to create image: {:?}", e);
99 | Response::builder()
100 | .status(500)
101 | .body("Error creating image".to_string())
102 | .unwrap()
103 | .into_response()
104 | }
105 | }
106 | }
107 |
108 | async fn execute_file_handler(
109 | uri: Uri,
110 | root: &str,
111 | ) -> Result