@@ -2,8 +2,11 @@ use regex::Regex;
22use serde_json:: Value ;
33use std:: path:: { Path , PathBuf } ;
44
5- use ml_cellar:: rack:: { RackConfig , load_config } ;
5+ use ml_cellar:: rack:: { RackConfig , load_rack_config } ;
66
7+ /// Looks up a value in a JSON object using a dot-separated path.
8+ /// This function traverses a JSON structure using a path string like "a.b.c"
9+ /// to access nested fields. It supports both object fields and array indices.
710fn lookup_json_path < ' a > ( root : & ' a Value , path : & str ) -> Option < & ' a Value > {
811 let mut cur = root;
912
@@ -24,6 +27,7 @@ fn lookup_json_path<'a>(root: &'a Value, path: &str) -> Option<&'a Value> {
2427 Some ( cur)
2528}
2629
30+ /// Converts a JSON value to a text string representation.
2731fn value_to_text ( v : & Value ) -> String {
2832 match v {
2933 // Delete " "
@@ -38,7 +42,11 @@ fn value_to_text(v: &Value) -> String {
3842 }
3943}
4044
41- /// Replace {a.b.c} in template file to JSON value
45+ /// Replaces placeholders in a markdown template with values from JSON data.
46+ /// This function finds all placeholders in the format `{a.b.c}` in the template
47+ /// and replaces them with corresponding values from the JSON data.
48+ /// If a placeholder is not found in the JSON, a warning is logged and the
49+ /// placeholder is kept as-is in the output.
4250fn render_markdown_template ( template : & str , data : & Value ) -> String {
4351 let re = Regex :: new ( r"\{([^{}]+)\}" ) . expect ( "invalid regex" ) ;
4452
@@ -57,6 +65,7 @@ fn render_markdown_template(template: &str, data: &Value) -> String {
5765 . to_string ( )
5866}
5967
68+ /// Loads the template markdown file specified in the rack configuration.
6069fn load_template_file ( config : & RackConfig , config_dir : & Path ) -> String {
6170 let template_file_path = config_dir. join ( config. document . template_file . as_ref ( ) . unwrap ( ) ) ;
6271 match std:: fs:: read_to_string ( & template_file_path) {
@@ -68,7 +77,10 @@ fn load_template_file(config: &RackConfig, config_dir: &Path) -> String {
6877 }
6978}
7079
71- fn load_result_json ( model_version_path : & Path , config : & RackConfig , config_dir : & Path ) -> Value {
80+ /// Loads and parses the result JSON file from the ML-bin directory.
81+ /// This function loads the JSON file containing evaluation results and metrics
82+ /// for the ML model, as specified in the rack configuration.
83+ fn load_result_json ( ml_bin_path : & Path , config : & RackConfig , config_dir : & Path ) -> Value {
7284 if config. document . result_file . is_none ( ) {
7385 log:: error!(
7486 "Documentation configuration is not set up in {:?}.\n
@@ -78,7 +90,7 @@ fn load_result_json(model_version_path: &Path, config: &RackConfig, config_dir:
7890 std:: process:: exit ( 1 ) ;
7991 }
8092
81- let result_file_path = model_version_path . join ( config. document . result_file . as_ref ( ) . unwrap ( ) ) ;
93+ let result_file_path = ml_bin_path . join ( config. document . result_file . as_ref ( ) . unwrap ( ) ) ;
8294
8395 let json_text = match std:: fs:: read_to_string ( & result_file_path) {
8496 Ok ( s) => s,
@@ -96,20 +108,40 @@ fn load_result_json(model_version_path: &Path, config: &RackConfig, config_dir:
96108 }
97109}
98110
99- pub fn docs ( model_version_path : PathBuf ) {
100- if !model_version_path. exists ( ) {
101- log:: error!( "{:?} does not exist" , model_version_path) ;
111+ /// Generates documentation for an ML-bin by rendering a template with result data.
112+ ///
113+ /// This function:
114+ /// 1. Loads the rack configuration
115+ /// 2. Loads the result JSON file from the ML-bin
116+ /// 3. Loads the template markdown file
117+ /// 4. Replaces `{{version}}` with the full model version path
118+ /// 5. Replaces `{field.name}` placeholders with values from the result JSON
119+ /// 6. Prints the rendered documentation
120+ ///
121+ /// # Arguments
122+ ///
123+ /// - `ml_bin_path` - Path to the ML-bin directory to generate documentation for
124+ ///
125+ /// # Panics
126+ ///
127+ /// Exits the process with code 1 if:
128+ /// - The ML-bin path does not exist
129+ /// - The configuration or result files cannot be loaded
130+ /// - Template rendering fails
131+ pub fn docs ( ml_bin_path : PathBuf ) {
132+ if !ml_bin_path. exists ( ) {
133+ log:: error!( "{:?} does not exist" , ml_bin_path) ;
102134 std:: process:: exit ( 1 ) ;
103135 }
104136
105- let ( config, config_dir) = load_config ( & model_version_path ) ;
106- let json_value = load_result_json ( & model_version_path , & config, & config_dir) ;
137+ let ( config, config_dir) = load_rack_config ( & ml_bin_path ) ;
138+ let json_value = load_result_json ( & ml_bin_path , & config, & config_dir) ;
107139 let template_text = load_template_file ( & config, & config_dir) ;
108140
109141 // Replace {{version}} with model version
110- let path_from_config_dir = model_version_path
142+ let path_from_config_dir = ml_bin_path
111143 . strip_prefix ( config_dir)
112- . unwrap_or ( & model_version_path )
144+ . unwrap_or ( & ml_bin_path )
113145 . to_path_buf ( ) ;
114146 let project_name = match path_from_config_dir. parent ( ) . and_then ( |p| p. to_str ( ) ) {
115147 Some ( s) => s. to_string ( ) ,
@@ -127,7 +159,7 @@ pub fn docs(model_version_path: PathBuf) {
127159 let rendered = render_markdown_template ( & rendered_version, & json_value) ;
128160 log:: info!(
129161 "Generate documentation for model version at path: {:?}" ,
130- model_version_path
162+ ml_bin_path
131163 ) ;
132164 print ! ( "\n \n {rendered} \n \n " ) ;
133165}
0 commit comments