2023-10-24 02:10:26 +00:00
use std ::path ::Path ;
use std ::path ::PathBuf ;
use crate ::config ::Config ;
use crate ::error ::CustomError ;
2023-10-24 01:51:15 +00:00
use super ::render_context ::GlobalSettings ;
2023-10-24 00:30:43 +00:00
use super ::render_context ::RenderBlogPostPage ;
2023-10-22 20:01:42 +00:00
use super ::BlogPost ;
2023-10-24 00:30:43 +00:00
use super ::BlogPostPage ;
2023-10-22 20:01:42 +00:00
2023-10-24 02:10:26 +00:00
pub ( crate ) fn convert_blog_post_page_to_render_context < D : AsRef < Path > , F : AsRef < Path > > (
config : & Config ,
output_directory : D ,
output_file : F ,
2023-10-24 00:30:43 +00:00
_post : & BlogPost ,
page : & BlogPostPage ,
2023-10-24 02:10:26 +00:00
) -> Result < RenderBlogPostPage , CustomError > {
let output_directory = output_directory . as_ref ( ) ;
let output_file = output_file . as_ref ( ) ;
let css_files = vec! [ get_web_path (
config ,
output_directory ,
output_file ,
" main.css " ,
) ? ] ;
let js_files = vec! [ get_web_path (
config ,
output_directory ,
output_file ,
" blog_post.js " ,
) ? ] ;
let global_settings = GlobalSettings ::new ( page . title . clone ( ) , css_files , js_files ) ;
2023-10-24 02:38:00 +00:00
let link_to_blog_post = get_web_path (
config ,
output_directory ,
output_file ,
output_file . strip_prefix ( output_directory ) ? ,
) ? ;
2023-10-24 02:10:26 +00:00
2023-10-24 02:38:00 +00:00
let ret = RenderBlogPostPage ::new ( global_settings , page . title . clone ( ) , Some ( link_to_blog_post ) ) ;
2023-10-24 02:10:26 +00:00
Ok ( ret )
}
fn get_web_path < D : AsRef < Path > , F : AsRef < Path > , P : AsRef < Path > > (
config : & Config ,
output_directory : D ,
containing_file : F ,
path_from_web_root : P ,
) -> Result < String , CustomError > {
let path_from_web_root = path_from_web_root . as_ref ( ) ;
if config . use_relative_paths ( ) {
let output_directory = output_directory . as_ref ( ) ;
let containing_file = containing_file . as_ref ( ) ;
2023-10-24 02:38:00 +00:00
let containing_file_relative_to_output_directory =
containing_file . strip_prefix ( output_directory ) ? ;
2023-10-24 02:10:26 +00:00
// Subtracting 1 from the depth to "remove" the file name.
2023-10-24 02:38:00 +00:00
let depth_from_web_root = containing_file_relative_to_output_directory
2023-10-24 02:10:26 +00:00
. components ( )
. count ( )
- 1 ;
let prefix = " ../ " . repeat ( depth_from_web_root ) ;
2023-10-24 02:38:00 +00:00
// TODO: It should be possible to strip some of the "../" components based on whether the path_from_web_root goes down the same path as the containing file.
2023-10-24 02:10:26 +00:00
let final_path = PathBuf ::from ( prefix ) . join ( path_from_web_root ) ;
let final_string = final_path
. as_path ( )
. to_str ( )
. map ( str ::to_string )
. ok_or ( " Path should be valid utf-8. " ) ? ;
Ok ( final_string )
} else {
let web_root = config
. get_web_root ( )
. ok_or ( " Must either use_relative_paths or set the web_root in the config. " ) ? ;
let final_path = PathBuf ::from ( web_root ) . join ( path_from_web_root ) ;
let final_string = final_path
. as_path ( )
. to_str ( )
. map ( str ::to_string )
. ok_or ( " Path should be valid utf-8. " ) ? ;
Ok ( final_string )
}
2023-10-22 20:01:42 +00:00
}
2023-10-24 02:38:00 +00:00
#[ allow(dead_code) ]
fn count_shared_steps < A : AsRef < Path > , B : AsRef < Path > > ( left : A , right : B ) -> usize {
let left = left . as_ref ( ) ;
let right = right . as_ref ( ) ;
left . components ( )
. zip ( right . components ( ) )
. position ( | ( l , r ) | l ! = r )
. unwrap_or_else ( | | left . components ( ) . count ( ) )
}
#[ cfg(test) ]
mod tests {
use super ::* ;
#[ test ]
fn test_count_shared_steps ( ) {
assert_eq! ( count_shared_steps ( " " , " " ) , 0 ) ;
assert_eq! ( count_shared_steps ( " foo.txt " , " foo.txt " ) , 1 ) ;
assert_eq! ( count_shared_steps ( " cat/foo.txt " , " dog/foo.txt " ) , 0 ) ;
assert_eq! (
count_shared_steps ( " foo/bar/baz/lorem.txt " , " foo/bar/ipsum/dolar.txt " ) ,
2
) ;
}
}