Rust library to generate static websites
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: whatever I guess

+117 -177
+117 -177
crates/maudit/src/build.rs
··· 41 41 async_runtime.block_on(async { build(routes, content_sources, options).await }) 42 42 } 43 43 44 - /// Represents a page to be built 45 - struct PageToBuild { 46 - /// The actual URL for this page (e.g., "/blog/my-post") 47 - url: String, 48 - /// The output file path 49 - file_path: PathBuf, 50 - /// Full page result for dynamic routes (params, props, typed_params) 51 - page_result: Option<( 52 - PageParams, 53 - crate::route::PageProps, 54 - crate::route::PageTypedParams, 55 - )>, 56 - /// Optional variant ID 57 - variant_id: Option<String>, 58 - /// Tree depth for logging (0 = base, 1 = variant/dynamic page) 59 - tree_depth: usize, 60 - } 61 - 62 - /// Represents a route header to log before its pages 63 - struct RouteHeader { 64 - pattern: String, 65 - tree_depth: usize, 66 - } 67 - 68 - enum BuildItem { 69 - Header(RouteHeader), 70 - Page(PageToBuild), 71 - } 72 - 73 - impl BuildItem { 74 - fn log_prefix(&self) -> &str { 75 - let tree_depth = match self { 76 - BuildItem::Header(h) => h.tree_depth, 77 - BuildItem::Page(p) => p.tree_depth, 78 - }; 79 - 80 - match tree_depth { 81 - 0 => "", 82 - 1 => "├─ ", 83 - _ => "│ ├─ ", 84 - } 44 + /// Returns the log prefix for a given tree depth 45 + fn log_prefix(tree_depth: usize) -> &'static str { 46 + match tree_depth { 47 + 0 => "", 48 + 1 => "├─ ", 49 + _ => "│ ├─ ", 85 50 } 86 51 } 87 52 ··· 177 142 178 143 trace!(target: "build", "Processing route: base='{}', variants={}", base_path, variants.len()); 179 144 180 - // Build list of items (headers + pages) to generate for this route 181 - let mut build_items: Vec<BuildItem> = Vec::new(); 145 + let has_base_route = !base_path.is_empty(); 182 146 183 147 // If no base route but has variants, show "(variants only)" header 184 - if base_path.is_empty() && !variants.is_empty() { 185 - build_items.push(BuildItem::Header(RouteHeader { 186 - pattern: "(variants only)".to_string(), 187 - tree_depth: 0, 188 - })); 148 + if !has_base_route && !variants.is_empty() { 149 + info!(target: "pages", "(variants only)"); 189 150 } 190 151 191 152 // Handle base route 192 - if !base_path.is_empty() { 153 + if has_base_route { 193 154 let base_params = extract_params_from_raw_route(&base_path); 194 - let is_dynamic = !base_params.is_empty(); 195 - 196 - if is_dynamic { 197 - // Add header for dynamic base route 198 - build_items.push(BuildItem::Header(RouteHeader { 199 - pattern: base_path.clone(), 200 - tree_depth: 0, 201 - })); 202 - } 203 155 204 156 if base_params.is_empty() { 205 157 // Static base route 158 + let mut route_assets = 159 + RouteAssets::new(&route_assets_options, Some(image_cache.clone())); 206 160 let params = PageParams::default(); 207 161 let url = cached_route.url(&params); 208 162 let file_path = cached_route.file_path(&params, &options.output_dir); 209 163 210 - build_items.push(BuildItem::Page(PageToBuild { 211 - url, 212 - file_path, 213 - page_result: None, 214 - variant_id: None, 215 - tree_depth: 0, 216 - })); 164 + let result = route.build(&mut PageContext::from_static_route( 165 + content_sources, 166 + &mut route_assets, 167 + &url, 168 + &options.base_url, 169 + None, 170 + ))?; 171 + 172 + write_route_file(&result, &file_path)?; 173 + 174 + info!(target: "pages", "{} -> {}", url, file_path.to_string_lossy().dimmed()); 175 + 176 + build_pages_images.extend(route_assets.images); 177 + build_pages_scripts.extend(route_assets.scripts); 178 + build_pages_styles.extend(route_assets.styles); 179 + 180 + build_metadata.add_page( 181 + base_path.clone(), 182 + file_path.to_string_lossy().to_string(), 183 + None, 184 + ); 185 + 186 + page_count += 1; 217 187 } else { 218 - // Dynamic base route - fetch pages 219 - let mut page_assets = 188 + // Dynamic base route 189 + let mut route_assets = 220 190 RouteAssets::new(&route_assets_options, Some(image_cache.clone())); 221 191 let pages = route.get_pages(&mut DynamicRouteContext { 222 192 content: content_sources, 223 - assets: &mut page_assets, 193 + assets: &mut route_assets, 224 194 variant: None, 225 195 }); 226 196 227 197 if pages.is_empty() { 228 198 warn!(target: "build", "{} has dynamic parameters but Route::pages returned an empty Vec. No pages will be generated.", base_path.bold()); 229 199 } else { 200 + // Log the pattern first 201 + info!(target: "pages", "{}", base_path); 202 + 203 + // Build all pages for this group 230 204 for page in pages { 231 205 let url = cached_route.url(&page.0); 232 206 let file_path = cached_route.file_path(&page.0, &options.output_dir); 233 207 234 - build_items.push(BuildItem::Page(PageToBuild { 235 - url, 236 - file_path, 237 - page_result: Some(page), 238 - variant_id: None, 239 - tree_depth: 1, 240 - })); 208 + let content = route.build(&mut PageContext::from_dynamic_route( 209 + &page, 210 + content_sources, 211 + &mut route_assets, 212 + &url, 213 + &options.base_url, 214 + None, 215 + ))?; 216 + 217 + write_route_file(&content, &file_path)?; 218 + 219 + info!(target: "pages", "{}{}", log_prefix(1), file_path.to_string_lossy().dimmed()); 220 + 221 + build_metadata.add_page( 222 + base_path.clone(), 223 + file_path.to_string_lossy().to_string(), 224 + Some(page.0.0.clone()), 225 + ); 226 + 227 + page_count += 1; 241 228 } 242 229 } 243 230 244 - build_pages_images.extend(page_assets.images); 245 - build_pages_scripts.extend(page_assets.scripts); 246 - build_pages_styles.extend(page_assets.styles); 231 + build_pages_images.extend(route_assets.images); 232 + build_pages_scripts.extend(route_assets.scripts); 233 + build_pages_styles.extend(route_assets.styles); 247 234 } 248 235 } 249 236 250 237 // Handle variants 251 238 for (variant_id, variant_path) in variants { 252 239 let variant_params = extract_params_from_raw_route(&variant_path); 253 - let is_dynamic = !variant_params.is_empty(); 254 - 255 - if is_dynamic { 256 - // Add header for dynamic variant 257 - build_items.push(BuildItem::Header(RouteHeader { 258 - pattern: variant_path.clone(), 259 - tree_depth: 1, 260 - })); 261 - } 240 + let variant_depth = 1; 262 241 263 242 if variant_params.is_empty() { 264 243 // Static variant 244 + let mut route_assets = 245 + RouteAssets::new(&route_assets_options, Some(image_cache.clone())); 246 + 265 247 let params = PageParams::default(); 266 248 let url = cached_route.variant_url(&params, &variant_id)?; 267 249 let file_path = 268 250 cached_route.variant_file_path(&params, &options.output_dir, &variant_id)?; 269 251 270 - build_items.push(BuildItem::Page(PageToBuild { 271 - url, 272 - file_path, 273 - page_result: None, 274 - variant_id: Some(variant_id.clone()), 275 - tree_depth: 1, 276 - })); 252 + let result = route.build(&mut PageContext::from_static_route( 253 + content_sources, 254 + &mut route_assets, 255 + &url, 256 + &options.base_url, 257 + Some(variant_id.clone()), 258 + ))?; 259 + 260 + write_route_file(&result, &file_path)?; 261 + 262 + info!(target: "pages", "{}{}", log_prefix(variant_depth), file_path.to_string_lossy().dimmed()); 263 + 264 + build_pages_images.extend(route_assets.images); 265 + build_pages_scripts.extend(route_assets.scripts); 266 + build_pages_styles.extend(route_assets.styles); 267 + 268 + build_metadata.add_page( 269 + format!("{} ({})", base_path, variant_id), 270 + file_path.to_string_lossy().to_string(), 271 + None, 272 + ); 273 + 274 + page_count += 1; 277 275 } else { 278 - // Dynamic variant - fetch pages 279 - let mut page_assets = 276 + // Dynamic variant 277 + let mut route_assets = 280 278 RouteAssets::new(&route_assets_options, Some(image_cache.clone())); 281 279 let pages = route.get_pages(&mut DynamicRouteContext { 282 280 content: content_sources, 283 - assets: &mut page_assets, 281 + assets: &mut route_assets, 284 282 variant: Some(&variant_id), 285 283 }); 286 284 287 285 if pages.is_empty() { 288 286 warn!(target: "build", "Variant {} has dynamic parameters but Route::pages returned an empty Vec.", variant_id.bold()); 289 287 } else { 288 + // Log the variant pattern first 289 + info!(target: "pages", "{}{}", log_prefix(variant_depth), variant_path); 290 + 291 + // Build all pages for this variant group 290 292 for page in pages { 291 293 let url = cached_route.variant_url(&page.0, &variant_id)?; 292 294 let file_path = cached_route.variant_file_path( ··· 295 297 &variant_id, 296 298 )?; 297 299 298 - build_items.push(BuildItem::Page(PageToBuild { 299 - url, 300 - file_path, 301 - page_result: Some(page), 302 - variant_id: Some(variant_id.clone()), 303 - tree_depth: 2, 304 - })); 305 - } 306 - } 307 - 308 - build_pages_images.extend(page_assets.images); 309 - build_pages_scripts.extend(page_assets.scripts); 310 - build_pages_styles.extend(page_assets.styles); 311 - } 312 - } 313 - 314 - // Now build all pages for this route and log as we go 315 - for build_item in build_items { 316 - match &build_item { 317 - BuildItem::Header(header) => { 318 - info!(target: "pages", "{}{}", build_item.log_prefix(), header.pattern); 319 - } 320 - BuildItem::Page(page_info) => { 321 - let mut route_assets = 322 - RouteAssets::new(&route_assets_options, Some(image_cache.clone())); 323 - 324 - let content = if let Some(ref page_result) = page_info.page_result { 325 - // Build dynamic page 326 - route.build(&mut PageContext::from_dynamic_route( 327 - page_result, 300 + let content = route.build(&mut PageContext::from_dynamic_route( 301 + &page, 328 302 content_sources, 329 303 &mut route_assets, 330 - &page_info.url, 304 + &url, 331 305 &options.base_url, 332 - page_info.variant_id.clone(), 333 - ))? 334 - } else { 335 - // Build static page 336 - route.build(&mut PageContext::from_static_route( 337 - content_sources, 338 - &mut route_assets, 339 - &page_info.url, 340 - &options.base_url, 341 - page_info.variant_id.clone(), 342 - ))? 343 - }; 306 + Some(variant_id.clone()), 307 + ))?; 344 308 345 - write_route_file(&content, &page_info.file_path)?; 309 + write_route_file(&content, &file_path)?; 346 310 347 - // Log immediately 348 - let log_line = if page_info.tree_depth == 0 && page_info.variant_id.is_none() { 349 - format!( 350 - "{} -> {}", 351 - page_info.url, 352 - page_info.file_path.to_string_lossy().dimmed() 353 - ) 354 - } else { 355 - format!( 356 - "{}{}", 357 - build_item.log_prefix(), 358 - page_info.file_path.to_string_lossy().dimmed() 359 - ) 360 - }; 361 - info!(target: "pages", "{}", log_line); 311 + info!(target: "pages", "{}{}", log_prefix(variant_depth + 1), file_path.to_string_lossy().dimmed()); 362 312 363 - // Add to metadata 364 - let metadata_route_name = if let Some(variant_id) = &page_info.variant_id { 365 - if base_path.is_empty() { 366 - format!("({})", variant_id) 367 - } else { 368 - format!("{} ({})", base_path, variant_id) 369 - } 370 - } else { 371 - base_path.clone() 372 - }; 373 - 374 - build_metadata.add_page( 375 - metadata_route_name, 376 - page_info.file_path.to_string_lossy().to_string(), 377 - page_info.page_result.as_ref().map(|pr| pr.0.0.clone()), 378 - ); 379 - 380 - build_pages_images.extend(route_assets.images); 381 - build_pages_scripts.extend(route_assets.scripts); 382 - build_pages_styles.extend(route_assets.styles); 313 + build_metadata.add_page( 314 + format!("{} ({})", base_path, variant_id), 315 + file_path.to_string_lossy().to_string(), 316 + Some(page.0.0.clone()), 317 + ); 383 318 384 - page_count += 1; 319 + page_count += 1; 320 + } 385 321 } 322 + 323 + build_pages_images.extend(route_assets.images); 324 + build_pages_scripts.extend(route_assets.scripts); 325 + build_pages_styles.extend(route_assets.styles); 386 326 } 387 327 } 388 328 }