From 6c9b0de571a16001bd957e125dd627417c748c53 Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Wed, 4 Jan 2023 11:39:37 +0530 Subject: [PATCH 01/11] fpm/dynamic-urls-fixes: changed the create-package-command added the downaload-base-url in it --- examples/dynamic-urls/FPM.ftd | 5 +++ examples/dynamic-urls/index.ftd | 1 + src/commands/create_package.rs | 68 +++++++++++++++++++-------------- src/main.rs | 4 +- 4 files changed, 49 insertions(+), 29 deletions(-) create mode 100644 examples/dynamic-urls/FPM.ftd create mode 100644 examples/dynamic-urls/index.ftd diff --git a/examples/dynamic-urls/FPM.ftd b/examples/dynamic-urls/FPM.ftd new file mode 100644 index 00000000..cdd3f900 --- /dev/null +++ b/examples/dynamic-urls/FPM.ftd @@ -0,0 +1,5 @@ + +-- import: fpm + +-- fpm.package: dynamic-urls +download-base-url: https://www.github.com/ diff --git a/examples/dynamic-urls/index.ftd b/examples/dynamic-urls/index.ftd new file mode 100644 index 00000000..f2a846c8 --- /dev/null +++ b/examples/dynamic-urls/index.ftd @@ -0,0 +1 @@ +-- ftd.text: Hello world \ No newline at end of file diff --git a/src/commands/create_package.rs b/src/commands/create_package.rs index baa200c2..4edb38f0 100644 --- a/src/commands/create_package.rs +++ b/src/commands/create_package.rs @@ -1,11 +1,22 @@ -async fn template_contents(project_name: &str) -> (String, String) { - let ftd = format!("-- import: fpm\n\n-- fpm.package: {}", project_name); +async fn template_contents(project_name: &str, download_base_url: &str) -> (String, String) { + let ftd = format!( + r#"-- import: fpm + +-- fpm.package: {} +download-base-url: {} +"#, + project_name, download_base_url + ); let index = "-- ftd.text: Hello world".to_string(); (ftd, index) } -pub async fn create_package(name: &str, path: Option<&str>) -> fpm::Result<()> { +pub async fn create_package( + name: &str, + path: Option<&str>, + download_base_url: Option<&str>, +) -> fpm::Result<()> { use colored::Colorize; let base_path = { @@ -36,38 +47,39 @@ pub async fn create_package(name: &str, path: Option<&str>) -> fpm::Result<()> { // Create all directories if not present tokio::fs::create_dir_all(final_dir.as_str()).await?; - let tmp_contents = template_contents(name).await; + let tmp_contents = template_contents(name, download_base_url.unwrap_or(name)).await; let tmp_fpm = tmp_contents.0; let tmp_index = tmp_contents.1; fpm::utils::update(&final_dir.join("FPM.ftd"), tmp_fpm.as_bytes()).await?; fpm::utils::update(&final_dir.join("index.ftd"), tmp_index.as_bytes()).await?; - let sync_message = "Initial sync".to_string(); - let file_list: std::collections::BTreeMap = - IntoIterator::into_iter([ - ( - "FPM.ftd".to_string(), - fpm::history::FileEditTemp { - message: Some(sync_message.to_string()), - author: None, - src_cr: None, - operation: fpm::history::FileOperation::Added, - }, - ), - ( - "index.ftd".to_string(), - fpm::history::FileEditTemp { - message: Some(sync_message.to_string()), - author: None, - src_cr: None, - operation: fpm::history::FileOperation::Added, - }, - ), - ]) - .collect(); + // Note: Not required for now + // let sync_message = "Initial sync".to_string(); + // let file_list: std::collections::BTreeMap = + // IntoIterator::into_iter([ + // ( + // "FPM.ftd".to_string(), + // fpm::history::FileEditTemp { + // message: Some(sync_message.to_string()), + // author: None, + // src_cr: None, + // operation: fpm::history::FileOperation::Added, + // }, + // ), + // ( + // "index.ftd".to_string(), + // fpm::history::FileEditTemp { + // message: Some(sync_message.to_string()), + // author: None, + // src_cr: None, + // operation: fpm::history::FileOperation::Added, + // }, + // ), + // ]) + // .collect(); - fpm::history::insert_into_history(&final_dir, &file_list, &mut Default::default()).await?; + // fpm::history::insert_into_history(&final_dir, &file_list, &mut Default::default()).await?; println!( "FPM Package Created: {}\nPath: {}", diff --git a/src/main.rs b/src/main.rs index 5505dc8b..3bc981f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,8 @@ async fn async_main() -> fpm::Result<()> { let name = project.value_of_("name").unwrap(); // project-path is optional let path = project.value_of_("path"); - return fpm::create_package(name, path).await; + let download_base_url = project.value_of_("download-base-url"); + return fpm::create_package(name, path, download_base_url).await; } if let Some(mark) = matches.subcommand_matches("serve") { @@ -208,6 +209,7 @@ fn app(version: &'static str) -> clap::Command { .about("Create a new FPM package") .arg(clap::arg!(name: "The name of the package to create")) .arg(clap::arg!(-p --path [PATH] "Where to create the package (relative or absolute path, default value: the name)")) + .arg(clap::arg!(--"download-base-url" "base url of the package where it can downloaded")) ) .subcommand( clap::Command::new("build") From f47b13c77e4f739d3d3c8914aa3b190c7a1d798c Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Wed, 4 Jan 2023 12:21:30 +0530 Subject: [PATCH 02/11] resolve dynamic urls is breaking --- src/config/mod.rs | 16 ++-------------- src/sitemap/dynamic_urls.rs | 3 +++ src/sitemap/mod.rs | 23 ++++++++++++++++++++++- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 3d30f3ed..6592d0e2 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -719,20 +719,8 @@ impl Config { }; // Getting `document` with dynamic parameters, if exists - let (document, path_params) = match sanitized_package.sitemap.as_ref() { - //1. First resolve document in sitemap - Some(sitemap) => match sitemap.resolve_document(sanitized_path.as_str()) { - Some(document) => (Some(document), vec![]), - //2. Else resolve document in dynamic urls - None => match sanitized_package.dynamic_urls.as_ref() { - Some(dynamic_urls) => { - dynamic_urls.resolve_document(sanitized_path.as_str())? - } - None => (None, vec![]), - }, - }, - None => (None, vec![]), - }; + let (document, path_params) = + fpm::sitemap::resolve_sitemap_or_dyn_urls(sanitized_package, &sanitized_path)?; // document with package-name prefix let document = document.map(|doc| { diff --git a/src/sitemap/dynamic_urls.rs b/src/sitemap/dynamic_urls.rs index 9c9e919a..5d2f7e4d 100644 --- a/src/sitemap/dynamic_urls.rs +++ b/src/sitemap/dynamic_urls.rs @@ -98,6 +98,7 @@ impl DynamicUrls { false } + #[tracing::instrument(name = "dynamic-urls-resolve-document")] pub fn resolve_document(&self, path: &str) -> fpm::Result { fn resolve_in_toc( toc: &fpm::sitemap::toc::TocItem, @@ -194,10 +195,12 @@ impl DynamicUrls { for section in self.sections.iter() { let (document, path_params) = resolve_in_section(section, path)?; if document.is_some() { + tracing::info!(msg = "return: document found", path = path); return Ok((document, path_params)); } } + tracing::info!(msg = "return: document not found", path = path); Ok((None, vec![])) } } diff --git a/src/sitemap/mod.rs b/src/sitemap/mod.rs index e5f62d04..e42114b2 100644 --- a/src/sitemap/mod.rs +++ b/src/sitemap/mod.rs @@ -1450,7 +1450,7 @@ impl Sitemap { /// path: foo/temp/ /// path: / /// This function can be used for if path exists in sitemap or not - #[tracing::instrument(skip_all)] + #[tracing::instrument(name = "sitemap-resolve-document", skip_all)] pub fn resolve_document(&self, path: &str) -> Option { tracing::info!(path = path); fn resolve_in_toc(toc: &toc::TocItem, path: &str) -> Option { @@ -1501,9 +1501,13 @@ impl Sitemap { for section in self.sections.iter() { let document = resolve_in_section(section, path); if document.is_some() { + tracing::info!(msg = "return: document found", path = path); return document; } } + + tracing::info!(msg = "return: document not found", path = path); + None } @@ -1635,3 +1639,20 @@ fn construct_tree(elements: Vec<(toc::TocItem, usize)>, smallest_level: usize) - } stack_tree } + +pub fn resolve_sitemap_or_dyn_urls( + package: &fpm::Package, + path: &str, +) -> fpm::Result<(Option, Vec<(String, ftd::Value)>)> { + if let Some(sitemap) = package.sitemap.as_ref() { + if let Some(document) = sitemap.resolve_document(path) { + return Ok((Some(document), vec![])); + } + }; + + if let Some(dynamic_urls) = package.dynamic_urls.as_ref() { + return dynamic_urls.resolve_document(path); + }; + + Ok((None, vec![])) +} From e61fdb41a3a71a9088e82bfb9b2ab82286ded5a5 Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Wed, 4 Jan 2023 12:26:19 +0530 Subject: [PATCH 03/11] fpm/dynamic-urls-fixes: added breaking examples --- examples/dynamic-urls/FPM.ftd | 14 ++++++++++++++ src/commands/serve.rs | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/examples/dynamic-urls/FPM.ftd b/examples/dynamic-urls/FPM.ftd index cdd3f900..3ed28120 100644 --- a/examples/dynamic-urls/FPM.ftd +++ b/examples/dynamic-urls/FPM.ftd @@ -3,3 +3,17 @@ -- fpm.package: dynamic-urls download-base-url: https://www.github.com/ + + +-- fpm.dynamic-urls: + +# TOC0 +url: /a//person/ +document: index.ftd + +- TOC1 +url: /b//person/ +document: index.ftd + - TOC2 + url: /c//person/ + document: index.ftd diff --git a/src/commands/serve.rs b/src/commands/serve.rs index d269e545..bd34d37b 100644 --- a/src/commands/serve.rs +++ b/src/commands/serve.rs @@ -285,7 +285,7 @@ pub async fn serve( // pass the url if the file is not static // So final check would be file is not static and path is not present in the package's sitemap tracing::info!( - "executing proxy: file-status: {}, path: {}", + "before executing proxy: file-status: {}, path: {}", file_response.status(), &path ); From 581b2d7460c1c3f191aacf8ee2c478a72406fcf1 Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Wed, 4 Jan 2023 13:56:39 +0530 Subject: [PATCH 04/11] fpm/dynamic-urls-fixes: added breaking cargo tests for parsing --- src/config/mod.rs | 2 +- src/sitemap/mod.rs | 4 +++- src/sitemap/utils.rs | 29 ++++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 6592d0e2..18cfe21f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -720,7 +720,7 @@ impl Config { // Getting `document` with dynamic parameters, if exists let (document, path_params) = - fpm::sitemap::resolve_sitemap_or_dyn_urls(sanitized_package, &sanitized_path)?; + fpm::sitemap::resolve(sanitized_package, &sanitized_path)?; // document with package-name prefix let document = document.map(|doc| { diff --git a/src/sitemap/mod.rs b/src/sitemap/mod.rs index e42114b2..c04a7d41 100644 --- a/src/sitemap/mod.rs +++ b/src/sitemap/mod.rs @@ -1640,16 +1640,18 @@ fn construct_tree(elements: Vec<(toc::TocItem, usize)>, smallest_level: usize) - stack_tree } -pub fn resolve_sitemap_or_dyn_urls( +pub fn resolve( package: &fpm::Package, path: &str, ) -> fpm::Result<(Option, Vec<(String, ftd::Value)>)> { + // resolve in sitemap if let Some(sitemap) = package.sitemap.as_ref() { if let Some(document) = sitemap.resolve_document(path) { return Ok((Some(document), vec![])); } }; + // resolve in dynamic-urls if let Some(dynamic_urls) = package.dynamic_urls.as_ref() { return dynamic_urls.resolve_document(path); }; diff --git a/src/sitemap/utils.rs b/src/sitemap/utils.rs index fb274ee6..cc80b573 100644 --- a/src/sitemap/utils.rs +++ b/src/sitemap/utils.rs @@ -19,7 +19,9 @@ pub fn parse_named_params( // This should go to config request [username: arpita, age: 28] if request_attrs.len().ne(&sitemap_attrs.len()) { - return Err(fpm::Error::GenericError("".to_string())); + return Err(fpm::Error::GenericError( + "request attributes and sitemap attributes are not same".to_string(), + )); } // [(param_name, value)] @@ -206,4 +208,29 @@ mod tests { assert!(output.is_err()) } + + // cargo test --package fpm --lib sitemap::utils::tests::parse_named_params_4 + #[test] + fn parse_named_params_4() { + let output = super::parse_named_params( + "/b/a/person/", + "/b//person/", + &[("string".to_string(), "username".to_string())], + ); + assert!(output.is_err()) + } + + // cargo test --package fpm --lib sitemap::utils::tests::parse_named_params_5 + #[test] + fn parse_named_params_5() { + let output = super::parse_named_params( + "/a/abrark/person/28/", + "/a//person/", + &[ + ("string".to_string(), "username".to_string()), + ("integer".to_string(), "age".to_string()), + ], + ); + assert!(output.is_err()) + } } From f754eac829928b903bd8a73d505bbc6b1aec3bca Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Thu, 5 Jan 2023 12:41:17 +0530 Subject: [PATCH 05/11] fpm/dynamic-urls: parsing the sitemap entry is done --- examples/dynamic-urls/bar/b.ftd | 0 examples/dynamic-urls/foo/a.ftd | 0 src/error.rs | 2 +- src/sitemap/dynamic_urls.rs | 2 +- src/sitemap/mod.rs | 2 +- src/sitemap/utils.rs | 115 +++++++++++++++++++++++++++++--- 6 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 examples/dynamic-urls/bar/b.ftd create mode 100644 examples/dynamic-urls/foo/a.ftd diff --git a/examples/dynamic-urls/bar/b.ftd b/examples/dynamic-urls/bar/b.ftd new file mode 100644 index 00000000..e69de29b diff --git a/examples/dynamic-urls/foo/a.ftd b/examples/dynamic-urls/foo/a.ftd new file mode 100644 index 00000000..e69de29b diff --git a/src/error.rs b/src/error.rs index 881f2204..98ea57f4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -87,7 +87,7 @@ impl Error { Self::GenericError(error.to_string()) } - pub fn generic_err + ToString>(error: T) -> fpm::Result<()> { + pub fn generic_err + ToString, O>(error: T) -> fpm::Result { Err(Self::generic(error)) } } diff --git a/src/sitemap/dynamic_urls.rs b/src/sitemap/dynamic_urls.rs index 5d2f7e4d..85fc5bb0 100644 --- a/src/sitemap/dynamic_urls.rs +++ b/src/sitemap/dynamic_urls.rs @@ -1,5 +1,5 @@ // document and path-parameters -type ResolveDocOutput = (Option, Vec<(String, ftd::Value)>); +pub(crate) type ResolveDocOutput = (Option, Vec<(String, ftd::Value)>); #[derive(Debug, serde::Deserialize, Clone)] pub struct DynamicUrlsTemp { diff --git a/src/sitemap/mod.rs b/src/sitemap/mod.rs index c04a7d41..10adbf31 100644 --- a/src/sitemap/mod.rs +++ b/src/sitemap/mod.rs @@ -1643,7 +1643,7 @@ fn construct_tree(elements: Vec<(toc::TocItem, usize)>, smallest_level: usize) - pub fn resolve( package: &fpm::Package, path: &str, -) -> fpm::Result<(Option, Vec<(String, ftd::Value)>)> { +) -> fpm::Result { // resolve in sitemap if let Some(sitemap) = package.sitemap.as_ref() { if let Some(document) = sitemap.resolve_document(path) { diff --git a/src/sitemap/utils.rs b/src/sitemap/utils.rs index cc80b573..06645d2d 100644 --- a/src/sitemap/utils.rs +++ b/src/sitemap/utils.rs @@ -1,5 +1,5 @@ // # Input -// request_url: /arpita/foo/28/ +// request_url: /abrark/foo/28/ // sitemap_url: //foo// // params_types: [(string, username), (integer, age)] // # Output @@ -11,13 +11,12 @@ pub fn parse_named_params( params_type: &[(String, String)], ) -> fpm::Result> { use itertools::Itertools; - // request_attrs: [arpita, foo, 28] + // request_attrs: [abrark, foo, 28] let request_attrs = request_url.trim_matches('/').split('/').collect_vec(); // sitemap_attrs: [, foo, ] let sitemap_attrs = sitemap_url.trim_matches('/').split('/').collect_vec(); - // This should go to config request [username: arpita, age: 28] - + // This should go to config request [username: abrark, age: 28] if request_attrs.len().ne(&sitemap_attrs.len()) { return Err(fpm::Error::GenericError( "request attributes and sitemap attributes are not same".to_string(), @@ -42,8 +41,7 @@ pub fn parse_named_params( let attribute_value = request_attrs[idx]; assert!(params_type.len() > type_matches_count); let attribute_type = ¶ms_type[type_matches_count].0; - dbg!(&attribute_value, attribute_type); - value_parse_to_type(attribute_value, attribute_type) + get_value_type(attribute_value, attribute_type) }; match parsed_value { Ok(value) => { @@ -57,7 +55,7 @@ pub fn parse_named_params( } return Ok(path_parameters); - fn value_parse_to_type(value: &str, r#type: &str) -> fpm::Result { + fn get_value_type(value: &str, r#type: &str) -> fpm::Result { match r#type { "string" => Ok(ftd::Value::String { text: value.to_string(), @@ -97,10 +95,98 @@ pub fn parse_path_params(url: &str) -> Vec<(String, String)> { .collect::>() } +// Input: /b///foo/ +// Output:vec![ +// (0, "b".to_string(), None), +// (1, "username".to_string(), Some("string".to_string())), +// (2, "age".to_string(), Some("integer".to_string())), +// (3, "foo".to_string(), None), +// ] +pub fn parse_path_params_new(url: &str) -> fpm::Result)>> { + let mut output = vec![]; + let url = url.trim().trim_matches('/'); + + // b///foo + let parts: Vec<&str> = url.split('/').collect(); + // parts: [b, , , foo] + let mut index = 0; + for part in parts { + let part = part.trim(); + if !part.is_empty() { + if part.contains(':') && part.starts_with('<') && part.ends_with('>') { + // + if let Some(colon_index) = part.find(':') { + let type_part = part[1..colon_index].trim(); + let param_name_part = part[colon_index + 1..part.len() - 1].trim(); + if type_part.is_empty() || param_name_part.is_empty() { + return fpm::Error::generic_err(format!( + "dynamic-urls format is wrong for: {}", + part + )); + } + output.push(( + index, + param_name_part.to_string(), + Some(type_part.to_string()), + )); + index += 1; + } + } else { + // b + output.push((index, part.to_string(), None)); + index += 1; + } + } + } + Ok(output) +} + #[cfg(test)] mod tests { use ftd::TextSource; + // cargo test --package fpm --lib sitemap::utils::tests::parse_path_params_test_0 + #[test] + fn parse_path_params_test_0() { + let output = super::parse_path_params_new("/b///foo/"); + let test_output = vec![ + (0, "b".to_string(), None), + (1, "username".to_string(), Some("string".to_string())), + (2, "age".to_string(), Some("integer".to_string())), + (3, "foo".to_string(), None), + ]; + assert!(output.is_ok()); + assert_eq!(test_output, output.unwrap()) + } + + // cargo test --package fpm --lib sitemap::utils::tests::parse_path_params_test_01 + #[test] + fn parse_path_params_test_01() { + let output = + super::parse_path_params_new("/b/ < string : username > / /foo/"); + let test_output = vec![ + (0, "b".to_string(), None), + (1, "username".to_string(), Some("string".to_string())), + (2, "age".to_string(), Some("integer".to_string())), + (3, "foo".to_string(), None), + ]; + assert!(output.is_ok()); + assert_eq!(test_output, output.unwrap()) + } + + // cargo test --package fpm --lib sitemap::utils::tests::parse_path_params_test_01 + #[test] + fn parse_path_params_test_02() { + let output = super::parse_path_params_new("/b/ < : username > / /foo/"); + // let test_output = vec![ + // (0, "b".to_string(), None), + // (1, "username".to_string(), Some("string".to_string())), + // (2, "age".to_string(), Some("integer".to_string())), + // (3, "foo".to_string(), None), + // ]; + assert!(output.is_err()) + } + #[test] fn parse_path_params_test_1() { let output = super::parse_path_params("///"); @@ -217,7 +303,18 @@ mod tests { "/b//person/", &[("string".to_string(), "username".to_string())], ); - assert!(output.is_err()) + assert!(output.is_ok()) + } + + // cargo test --package fpm --lib sitemap::utils::tests::parse_named_params_4_1 + #[test] + fn parse_named_params_4_1() { + let output = super::parse_named_params( + "/b/a/person/", + "/a//person/", + &[("string".to_string(), "username".to_string())], + ); + assert!(output.is_ok()) } // cargo test --package fpm --lib sitemap::utils::tests::parse_named_params_5 @@ -231,6 +328,6 @@ mod tests { ("integer".to_string(), "age".to_string()), ], ); - assert!(output.is_err()) + assert!(output.is_ok()) } } From 31812185d62f1c24d72ca03776596cd0121387fe Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Thu, 5 Jan 2023 12:56:42 +0530 Subject: [PATCH 06/11] fpm/dynamic-urls: change the type in sitemap for path params --- src/sitemap/mod.rs | 7 +++--- src/sitemap/section.rs | 8 ++++--- src/sitemap/toc.rs | 2 +- src/sitemap/utils.rs | 52 +++++++----------------------------------- 4 files changed, 18 insertions(+), 51 deletions(-) diff --git a/src/sitemap/mod.rs b/src/sitemap/mod.rs index 10adbf31..cb526767 100644 --- a/src/sitemap/mod.rs +++ b/src/sitemap/mod.rs @@ -179,8 +179,8 @@ impl SitemapElement { // If url contains path parameters so it will set those parameters // /person// // In that case it will parse and set parameters `username` and `age` - pub(crate) fn set_path_params(&mut self, url: &str) { - let params = utils::parse_path_params(url); + pub(crate) fn set_path_params(&mut self, url: &str) -> Result<(), ParseError> { + let params = utils::parse_path_params_new(url)?; if !params.is_empty() { self.set_skip(true); @@ -197,6 +197,7 @@ impl SitemapElement { t.path_parameters = params; } } + Ok(()) } } @@ -453,7 +454,7 @@ impl SitemapParser { if i.get_title().is_none() { i.set_title(id); } - i.set_path_params(v); + i.set_path_params(v)?; } else if k.eq("id") { // Fetch link corresponding to the id from global_ids map let link = global_ids.get(v).ok_or_else(|| ParseError::InvalidID { diff --git a/src/sitemap/section.rs b/src/sitemap/section.rs index 798b5e46..da8dc75d 100644 --- a/src/sitemap/section.rs +++ b/src/sitemap/section.rs @@ -116,8 +116,8 @@ pub struct Section { /// If we can define dynamic `url` in section, subsection and toc in `dynamic-urls`. /// `url: /books///` /// here book_name and price are path parameters - /// path_parameters: [(string, book_name), (integer, price)] - pub path_parameters: Vec<(String, String)>, + /// [(0, books, None), (1, book_name, string), (2, price, integer)] + pub path_parameters: Vec<(usize, String, Option)>, } impl Default for Section { @@ -164,9 +164,11 @@ pub struct Subsection { /// `confidential:true` means totally confidential /// `confidential:false` can be seen some it's data pub confidential: bool, + /// /books// /// here book_name is path parameter - pub path_parameters: Vec<(String, String)>, + /// [(0, books, None), (1, book_name, string)] + pub path_parameters: Vec<(usize, String, Option)>, } impl Section { diff --git a/src/sitemap/toc.rs b/src/sitemap/toc.rs index c0121c3d..8dacbba4 100644 --- a/src/sitemap/toc.rs +++ b/src/sitemap/toc.rs @@ -20,7 +20,7 @@ pub struct TocItem { pub confidential: bool, /// /books// /// here book_name is path parameter - pub path_parameters: Vec<(String, String)>, + pub path_parameters: Vec<(usize, String, Option)>, } impl Default for TocItem { diff --git a/src/sitemap/utils.rs b/src/sitemap/utils.rs index 06645d2d..29caaa5a 100644 --- a/src/sitemap/utils.rs +++ b/src/sitemap/utils.rs @@ -4,11 +4,11 @@ // params_types: [(string, username), (integer, age)] // # Output // true - +// TODO: This should be match method pub fn parse_named_params( request_url: &str, sitemap_url: &str, - params_type: &[(String, String)], + params_type: &[(usize, String, Option)], ) -> fpm::Result> { use itertools::Itertools; // request_attrs: [abrark, foo, 28] @@ -78,23 +78,6 @@ pub fn parse_named_params( } } -// url: /// => [("string", "username"), ("integer", "age")] -pub fn parse_path_params(url: &str) -> Vec<(String, String)> { - fn path_params_regex() -> &'static regex::Regex { - static PP: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); - PP.get_or_init(|| { - regex::Regex::new(r"<\s*([a-z]\w+)\s*:\s*([a-z|A-Z|0-9|_]\w+)\s*>") - .expect("PATH_PARAMS: Regex is wrong") - }) - } - - path_params_regex() - .captures_iter(url) - .into_iter() - .map(|params| (params[1].to_string(), params[2].to_string())) - .collect::>() -} - // Input: /b///foo/ // Output:vec![ // (0, "b".to_string(), None), @@ -102,7 +85,9 @@ pub fn parse_path_params(url: &str) -> Vec<(String, String)> { // (2, "age".to_string(), Some("integer".to_string())), // (3, "foo".to_string(), None), // ] -pub fn parse_path_params_new(url: &str) -> fpm::Result)>> { +pub fn parse_path_params_new( + url: &str, +) -> Result)>, fpm::sitemap::ParseError> { let mut output = vec![]; let url = url.trim().trim_matches('/'); @@ -119,10 +104,9 @@ pub fn parse_path_params_new(url: &str) -> fpm::Result//"); - let test_output = vec![ - ("string".to_string(), "username".to_string()), - ("integer".to_string(), "age".to_string()), - ]; - assert_eq!(test_output, output) - } - - #[test] - fn parse_path_params_test_2() { - let output = super::parse_path_params("/< string: username >/< integer: age >/"); - let test_output = vec![ - ("string".to_string(), "username".to_string()), - ("integer".to_string(), "age".to_string()), - ]; - assert_eq!(test_output, output) - } - #[test] fn parse_named_params() { let output = super::parse_named_params( From 68bcb016de64226b66b02c34357405056e0455fa Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Thu, 5 Jan 2023 14:07:03 +0530 Subject: [PATCH 07/11] fpm/dynamic-urls: request url matching is done with dynamic url --- src/config/mod.rs | 2 + src/sitemap/dynamic_urls.rs | 44 +++---- src/sitemap/mod.rs | 2 +- src/sitemap/utils.rs | 234 ++++++++++++++++++------------------ 4 files changed, 141 insertions(+), 141 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 18cfe21f..1c78e569 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -719,6 +719,8 @@ impl Config { }; // Getting `document` with dynamic parameters, if exists + // It will first resolve in sitemap + // Then it will resolve in the dynamic urls let (document, path_params) = fpm::sitemap::resolve(sanitized_package, &sanitized_path)?; diff --git a/src/sitemap/dynamic_urls.rs b/src/sitemap/dynamic_urls.rs index 85fc5bb0..7d007dce 100644 --- a/src/sitemap/dynamic_urls.rs +++ b/src/sitemap/dynamic_urls.rs @@ -109,14 +109,10 @@ impl DynamicUrls { // request: arpita foo 28 // sitemap: [string,integer] // Mapping: arpita -> string, foo -> foo, 28 -> integer - let params = fpm::sitemap::utils::parse_named_params( - path, - toc.id.as_str(), - toc.path_parameters.as_slice(), - ); + let params = fpm::sitemap::utils::url_match(path, toc.path_parameters.as_slice())?; - if params.is_ok() { - return Ok((toc.document.clone(), params?)); + if params.0 { + return Ok((toc.document.clone(), params.1)); } } @@ -139,16 +135,11 @@ impl DynamicUrls { // request: arpita foo 28 // sitemap: [string,integer] // Mapping: arpita -> string, foo -> foo, 28 -> integer - if let Some(id) = sub_section.id.as_ref() { - let params = fpm::sitemap::utils::parse_named_params( - path, - id.as_str(), - sub_section.path_parameters.as_slice(), - ); + let params = + fpm::sitemap::utils::url_match(path, sub_section.path_parameters.as_slice())?; - if params.is_ok() { - return Ok((sub_section.document.clone(), params?)); - } + if params.0 { + return Ok((sub_section.document.clone(), params.1)); } } for toc in sub_section.toc.iter() { @@ -172,14 +163,11 @@ impl DynamicUrls { // request: abrark foo 28 // sitemap: [string,integer] // params_matches: abrark -> string, foo -> foo, 28 -> integer - let params = fpm::sitemap::utils::parse_named_params( - path, - section.id.as_str(), - section.path_parameters.as_slice(), - ); + let params = + fpm::sitemap::utils::url_match(path, section.path_parameters.as_slice())?; - if params.is_ok() { - return Ok((section.document.clone(), params?)); + if params.0 { + return Ok((section.document.clone(), params.1)); } } @@ -276,7 +264,10 @@ mod tests { readers: vec!["readers/person".to_string()], writers: vec!["writers/person".to_string()], document: Some("person.ftd".to_string()), - path_parameters: vec![("string".to_string(), "name".to_string())], + path_parameters: vec![ + (0, "person".to_string(), None), + (1, "name".to_string(), Some("string".to_string())), + ], confidential: true, }, fpm::sitemap::toc::TocItem { @@ -302,7 +293,10 @@ mod tests { readers: vec!["readers/person".to_string()], writers: vec!["writers/person".to_string()], document: Some("person.ftd".to_string()), - path_parameters: vec![("string".to_string(), "name".to_string())], + path_parameters: vec![ + (0, "person".to_string(), None), + (1, "name".to_string(), Some("string".to_string())), + ], confidential: true, }, ], diff --git a/src/sitemap/mod.rs b/src/sitemap/mod.rs index cb526767..9b1959cb 100644 --- a/src/sitemap/mod.rs +++ b/src/sitemap/mod.rs @@ -180,7 +180,7 @@ impl SitemapElement { // /person// // In that case it will parse and set parameters `username` and `age` pub(crate) fn set_path_params(&mut self, url: &str) -> Result<(), ParseError> { - let params = utils::parse_path_params_new(url)?; + let params = utils::parse_path_params(url)?; if !params.is_empty() { self.set_skip(true); diff --git a/src/sitemap/utils.rs b/src/sitemap/utils.rs index 29caaa5a..6d5e85e2 100644 --- a/src/sitemap/utils.rs +++ b/src/sitemap/utils.rs @@ -4,56 +4,50 @@ // params_types: [(string, username), (integer, age)] // # Output // true -// TODO: This should be match method -pub fn parse_named_params( + +/* +enum PathParams { + NamedParm{index: usize, param_name: String, param_type: String} + Param{index: usize, value: String} +} +*/ + +pub fn url_match( request_url: &str, - sitemap_url: &str, - params_type: &[(usize, String, Option)], -) -> fpm::Result> { + sitemap_params: &[(usize, String, Option)], +) -> fpm::Result<(bool, Vec<(String, ftd::Value)>)> { use itertools::Itertools; // request_attrs: [abrark, foo, 28] - let request_attrs = request_url.trim_matches('/').split('/').collect_vec(); - // sitemap_attrs: [, foo, ] - let sitemap_attrs = sitemap_url.trim_matches('/').split('/').collect_vec(); - + let request_parts = request_url.trim_matches('/').split('/').collect_vec(); // This should go to config request [username: abrark, age: 28] - if request_attrs.len().ne(&sitemap_attrs.len()) { - return Err(fpm::Error::GenericError( - "request attributes and sitemap attributes are not same".to_string(), - )); + if request_parts.len().ne(&sitemap_params.len()) { + return Ok((false, vec![])); } + // match logic + // req: [a, ak, foo] + // d-urls: [(0, a, None), (1, username, Some(string)), (2, foo, None)] // [(param_name, value)] let mut path_parameters: Vec<(String, ftd::Value)> = vec![]; - - // For every element either value should match or request attribute type should match to - // sitemap's params_types - let mut type_matches_count = 0; - for idx in 0..request_attrs.len() { - // either value match or type match - let value_match = request_attrs[idx].eq(sitemap_attrs[idx]); - if value_match { - continue; - } - - let parsed_value = { - // request's attribute value type == type stored in sitemap:params_type - let attribute_value = request_attrs[idx]; - assert!(params_type.len() > type_matches_count); - let attribute_type = ¶ms_type[type_matches_count].0; - get_value_type(attribute_value, attribute_type) - }; - match parsed_value { - Ok(value) => { - let attribute_name = params_type[type_matches_count].1.to_string(); - path_parameters.push((attribute_name, value)); + let mut index = 0; + for req_part in request_parts { + let (_idx, value_or_param_name, value_type) = &sitemap_params[index]; + index += 1; // Note: Use it carefully next + if value_type.is_none() { + if req_part.eq(value_or_param_name) { + continue; + } else { + return Ok((false, vec![])); } - Err(e) => return Err(fpm::Error::GenericError(e.to_string())), - }; - - type_matches_count += 1; + } else { + if let Ok(value) = get_value_type(req_part, value_type.as_ref().unwrap()) { + path_parameters.push((value_or_param_name.to_string(), value)); + } else { + return Ok((false, vec![])); + } + } } - return Ok(path_parameters); + return Ok((true, path_parameters)); fn get_value_type(value: &str, r#type: &str) -> fpm::Result { match r#type { @@ -78,14 +72,9 @@ pub fn parse_named_params( } } -// Input: /b///foo/ -// Output:vec![ -// (0, "b".to_string(), None), -// (1, "username".to_string(), Some("string".to_string())), -// (2, "age".to_string(), Some("integer".to_string())), -// (3, "foo".to_string(), None), -// ] -pub fn parse_path_params_new( +/// Please check test case: `parse_path_params_test_0` +/// This method is for parsing the dynamic params from fpm.dynamic-urls +pub fn parse_path_params( url: &str, ) -> Result)>, fpm::sitemap::ParseError> { let mut output = vec![]; @@ -95,8 +84,7 @@ pub fn parse_path_params_new( let parts: Vec<&str> = url.split('/').collect(); // parts: [b, , , foo] let mut index = 0; - for part in parts { - let part = part.trim(); + for part in parts.into_iter().map(|x| x.trim()) { if !part.is_empty() { if part.contains(':') && part.starts_with('<') && part.ends_with('>') { // @@ -132,7 +120,7 @@ mod tests { // cargo test --package fpm --lib sitemap::utils::tests::parse_path_params_test_0 #[test] fn parse_path_params_test_0() { - let output = super::parse_path_params_new("/b///foo/"); + let output = super::parse_path_params("/b///foo/"); let test_output = vec![ (0, "b".to_string(), None), (1, "username".to_string(), Some("string".to_string())), @@ -146,8 +134,7 @@ mod tests { // cargo test --package fpm --lib sitemap::utils::tests::parse_path_params_test_01 #[test] fn parse_path_params_test_01() { - let output = - super::parse_path_params_new("/b/ < string : username > / /foo/"); + let output = super::parse_path_params("/b/ < string : username > / /foo/"); let test_output = vec![ (0, "b".to_string(), None), (1, "username".to_string(), Some("string".to_string())), @@ -161,7 +148,7 @@ mod tests { // cargo test --package fpm --lib sitemap::utils::tests::parse_path_params_test_01 #[test] fn parse_path_params_test_02() { - let output = super::parse_path_params_new("/b/ < : username > / /foo/"); + let output = super::parse_path_params("/b/ < : username > / /foo/"); // let test_output = vec![ // (0, "b".to_string(), None), // (1, "username".to_string(), Some("string".to_string())), @@ -171,19 +158,23 @@ mod tests { assert!(output.is_err()) } + // cargo test --package fpm --lib sitemap::utils::tests::url_match -- --nocapture #[test] - fn parse_named_params() { - let output = super::parse_named_params( + fn url_match() { + // "//foo//", + let output = super::url_match( "/arpita/foo/28/", - "//foo//", &[ - ("string".to_string(), "username".to_string()), - ("integer".to_string(), "age".to_string()), + (0, "username".to_string(), Some("string".to_string())), + (1, "foo".to_string(), None), + (2, "age".to_string(), Some("integer".to_string())), ], ); + let output = output.unwrap(); + assert!(output.0); assert_eq!( - output.unwrap(), + output.1, vec![ ( "username".to_string(), @@ -197,101 +188,114 @@ mod tests { ) } + // cargo test --package fpm --lib sitemap::utils::tests::url_match_2 -- --nocapture #[test] - fn parse_named_params_1() { - // Input: - // request_url: /arpita/foo/28/ - // sitemap_url: //foo// - // params_types: [(string, username), (integer, age)] - // Output: true - // Reason: Everything is matching - - let output = super::parse_named_params( - "/arpita/foo/28/", - "//foo//", - &[ - ("string".to_string(), "username".to_string()), - ("integer".to_string(), "age".to_string()), - ], - ); - - assert!(output.is_ok()) - } - - #[test] - fn parse_named_params_2() { + fn url_match_2() { // Input: // request_url: /arpita/foo/28/ // sitemap_url: //foo// - // params_types: [(integer, username), (integer, age)] // Output: false // Reason: `arpita` can not be converted into `integer` - let output = super::parse_named_params( + let output = super::url_match( "/arpita/foo/28/", - "//foo//", &[ - ("integer".to_string(), "username".to_string()), - ("integer".to_string(), "age".to_string()), + (0, "username".to_string(), Some("integer".to_string())), + (1, "foo".to_string(), None), + (2, "age".to_string(), Some("integer".to_string())), ], ); - assert!(output.is_err()) + assert!(!output.unwrap().0) } + // cargo test --package fpm --lib sitemap::utils::tests::url_match_3 #[test] - fn parse_named_params_3() { + fn url_match_3() { // Input: // request_url: /arpita/foo/ // sitemap_url: //foo// - // params_types: [(string, username), (integer, age)] // Output: false // Reason: There is nothing to match in request_url after `foo` // against with sitemap_url `` - let output = super::parse_named_params( + let output = super::url_match( "/arpita/foo/", - "//foo//", &[ - ("string".to_string(), "username".to_string()), - ("integer".to_string(), "age".to_string()), + (0, "username".to_string(), Some("integer".to_string())), + (1, "foo".to_string(), None), + (2, "age".to_string(), Some("integer".to_string())), ], ); - - assert!(output.is_err()) + assert!(!output.unwrap().0) } - // cargo test --package fpm --lib sitemap::utils::tests::parse_named_params_4 + // cargo test --package fpm --lib sitemap::utils::tests::url_match_4 -- --nocapture #[test] - fn parse_named_params_4() { - let output = super::parse_named_params( + fn url_match_4() { + // sitemap_url: /b//person/, + let output = super::url_match( "/b/a/person/", - "/b//person/", - &[("string".to_string(), "username".to_string())], + &[ + (0, "b".to_string(), None), + (1, "username".to_string(), Some("string".to_string())), + (2, "person".to_string(), None), + ], ); - assert!(output.is_ok()) + let output = output.unwrap(); + assert!(output.0); + assert_eq!( + output.1, + vec![( + "username".to_string(), + ftd::Value::String { + text: "a".to_string(), + source: TextSource::Default + } + )] + ) } - // cargo test --package fpm --lib sitemap::utils::tests::parse_named_params_4_1 + // cargo test --package fpm --lib sitemap::utils::tests::url_match_4_1 #[test] - fn parse_named_params_4_1() { - let output = super::parse_named_params( + fn url_match_4_1() { + // sitemap_url: /a//person/, + let output = super::url_match( "/b/a/person/", - "/a//person/", - &[("string".to_string(), "username".to_string())], + &[ + (0, "a".to_string(), None), + (1, "username".to_string(), Some("string".to_string())), + (2, "person".to_string(), None), + ], ); - assert!(output.is_ok()) + assert!(!output.unwrap().0) } - // cargo test --package fpm --lib sitemap::utils::tests::parse_named_params_5 + // cargo test --package fpm --lib sitemap::utils::tests::url_match_5 -- --nocapture #[test] - fn parse_named_params_5() { - let output = super::parse_named_params( + fn url_match_5() { + // sitemap_url: /a//person/ + let output = super::url_match( "/a/abrark/person/28/", - "/a//person/", &[ - ("string".to_string(), "username".to_string()), - ("integer".to_string(), "age".to_string()), + (0, "a".to_string(), None), + (1, "username".to_string(), Some("string".to_string())), + (2, "person".to_string(), None), + (3, "age".to_string(), Some("integer".to_string())), ], ); - assert!(output.is_ok()) + let output = output.unwrap(); + assert!(output.0); + assert_eq!( + output.1, + vec![ + ( + "username".to_string(), + ftd::Value::String { + text: "abrark".to_string(), + source: TextSource::Default + } + ), + ("age".to_string(), ftd::Value::Integer { value: 28 }) + ] + ); } } From 6672b57473c5d30ff315225b29c61ae6ab88b1ff Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Thu, 5 Jan 2023 14:36:30 +0530 Subject: [PATCH 08/11] fpm/dynamic-urls: change the type of the parsed parameters --- src/sitemap/dynamic_urls.rs | 16 ++++-- src/sitemap/mod.rs | 27 ++++++++++ src/sitemap/section.rs | 4 +- src/sitemap/toc.rs | 2 +- src/sitemap/utils.rs | 105 ++++++++++++++++++------------------ 5 files changed, 95 insertions(+), 59 deletions(-) diff --git a/src/sitemap/dynamic_urls.rs b/src/sitemap/dynamic_urls.rs index 7d007dce..017c5b38 100644 --- a/src/sitemap/dynamic_urls.rs +++ b/src/sitemap/dynamic_urls.rs @@ -265,8 +265,12 @@ mod tests { writers: vec!["writers/person".to_string()], document: Some("person.ftd".to_string()), path_parameters: vec![ - (0, "person".to_string(), None), - (1, "name".to_string(), Some("string".to_string())), + fpm::sitemap::PathParams::value(0, "person".to_string()), + fpm::sitemap::PathParams::named( + 1, + "name".to_string(), + "string".to_string(), + ), ], confidential: true, }, @@ -294,8 +298,12 @@ mod tests { writers: vec!["writers/person".to_string()], document: Some("person.ftd".to_string()), path_parameters: vec![ - (0, "person".to_string(), None), - (1, "name".to_string(), Some("string".to_string())), + fpm::sitemap::PathParams::value(0, "person".to_string()), + fpm::sitemap::PathParams::named( + 1, + "name".to_string(), + "string".to_string(), + ), ], confidential: true, }, diff --git a/src/sitemap/mod.rs b/src/sitemap/mod.rs index 9b1959cb..74a0657c 100644 --- a/src/sitemap/mod.rs +++ b/src/sitemap/mod.rs @@ -49,6 +49,33 @@ pub enum SitemapElement { TocItem(toc::TocItem), } +#[derive(Debug, Clone, PartialEq)] +pub enum PathParams { + NamedParm { + index: usize, + name: String, + param_type: String, + }, + ValueParam { + index: usize, + value: String, + }, +} + +impl PathParams { + pub fn named(index: usize, name: String, param_type: String) -> Self { + PathParams::NamedParm { + index, + name, + param_type, + } + } + + pub fn value(index: usize, value: String) -> Self { + PathParams::ValueParam { index, value } + } +} + impl SitemapElement { pub(crate) fn insert_key_value(&mut self, key: &str, value: &str) { let element_title = match self { diff --git a/src/sitemap/section.rs b/src/sitemap/section.rs index da8dc75d..8261d6a4 100644 --- a/src/sitemap/section.rs +++ b/src/sitemap/section.rs @@ -117,7 +117,7 @@ pub struct Section { /// `url: /books///` /// here book_name and price are path parameters /// [(0, books, None), (1, book_name, string), (2, price, integer)] - pub path_parameters: Vec<(usize, String, Option)>, + pub path_parameters: Vec, } impl Default for Section { @@ -168,7 +168,7 @@ pub struct Subsection { /// /books// /// here book_name is path parameter /// [(0, books, None), (1, book_name, string)] - pub path_parameters: Vec<(usize, String, Option)>, + pub path_parameters: Vec, } impl Section { diff --git a/src/sitemap/toc.rs b/src/sitemap/toc.rs index 8dacbba4..edb437b3 100644 --- a/src/sitemap/toc.rs +++ b/src/sitemap/toc.rs @@ -20,7 +20,7 @@ pub struct TocItem { pub confidential: bool, /// /books// /// here book_name is path parameter - pub path_parameters: Vec<(usize, String, Option)>, + pub path_parameters: Vec, } impl Default for TocItem { diff --git a/src/sitemap/utils.rs b/src/sitemap/utils.rs index 6d5e85e2..a45b54ad 100644 --- a/src/sitemap/utils.rs +++ b/src/sitemap/utils.rs @@ -14,7 +14,7 @@ enum PathParams { pub fn url_match( request_url: &str, - sitemap_params: &[(usize, String, Option)], + sitemap_params: &[fpm::sitemap::PathParams], ) -> fpm::Result<(bool, Vec<(String, ftd::Value)>)> { use itertools::Itertools; // request_attrs: [abrark, foo, 28] @@ -29,23 +29,30 @@ pub fn url_match( // d-urls: [(0, a, None), (1, username, Some(string)), (2, foo, None)] // [(param_name, value)] let mut path_parameters: Vec<(String, ftd::Value)> = vec![]; - let mut index = 0; + let mut count = 0; for req_part in request_parts { - let (_idx, value_or_param_name, value_type) = &sitemap_params[index]; - index += 1; // Note: Use it carefully next - if value_type.is_none() { - if req_part.eq(value_or_param_name) { - continue; - } else { - return Ok((false, vec![])); + match &sitemap_params[count] { + fpm::sitemap::PathParams::ValueParam { index: _, value } => { + count += 1; + if req_part.eq(value) { + continue; + } else { + return Ok((false, vec![])); + } } - } else { - if let Ok(value) = get_value_type(req_part, value_type.as_ref().unwrap()) { - path_parameters.push((value_or_param_name.to_string(), value)); - } else { - return Ok((false, vec![])); + fpm::sitemap::PathParams::NamedParm { + index: _, + name, + param_type, + } => { + count += 1; + if let Ok(value) = get_value_type(req_part, param_type) { + path_parameters.push((name.to_string(), value)); + } else { + return Ok((false, vec![])); + } } - } + }; } return Ok((true, path_parameters)); @@ -76,7 +83,7 @@ pub fn url_match( /// This method is for parsing the dynamic params from fpm.dynamic-urls pub fn parse_path_params( url: &str, -) -> Result)>, fpm::sitemap::ParseError> { +) -> Result, fpm::sitemap::ParseError> { let mut output = vec![]; let url = url.trim().trim_matches('/'); @@ -96,16 +103,16 @@ pub fn parse_path_params( message: format!("dynamic-urls format is wrong for: {}", part), }); } - output.push(( + output.push(fpm::sitemap::PathParams::named( index, param_name_part.to_string(), - Some(type_part.to_string()), + type_part.to_string(), )); index += 1; } } else { // b - output.push((index, part.to_string(), None)); + output.push(fpm::sitemap::PathParams::value(index, part.to_string())); index += 1; } } @@ -122,10 +129,10 @@ mod tests { fn parse_path_params_test_0() { let output = super::parse_path_params("/b///foo/"); let test_output = vec![ - (0, "b".to_string(), None), - (1, "username".to_string(), Some("string".to_string())), - (2, "age".to_string(), Some("integer".to_string())), - (3, "foo".to_string(), None), + fpm::sitemap::PathParams::value(0, "b".to_string()), + fpm::sitemap::PathParams::named(1, "username".to_string(), "string".to_string()), + fpm::sitemap::PathParams::named(2, "age".to_string(), "integer".to_string()), + fpm::sitemap::PathParams::value(3, "foo".to_string()), ]; assert!(output.is_ok()); assert_eq!(test_output, output.unwrap()) @@ -136,10 +143,10 @@ mod tests { fn parse_path_params_test_01() { let output = super::parse_path_params("/b/ < string : username > / /foo/"); let test_output = vec![ - (0, "b".to_string(), None), - (1, "username".to_string(), Some("string".to_string())), - (2, "age".to_string(), Some("integer".to_string())), - (3, "foo".to_string(), None), + fpm::sitemap::PathParams::value(0, "b".to_string()), + fpm::sitemap::PathParams::named(1, "username".to_string(), "string".to_string()), + fpm::sitemap::PathParams::named(2, "age".to_string(), "integer".to_string()), + fpm::sitemap::PathParams::value(3, "foo".to_string()), ]; assert!(output.is_ok()); assert_eq!(test_output, output.unwrap()) @@ -149,12 +156,6 @@ mod tests { #[test] fn parse_path_params_test_02() { let output = super::parse_path_params("/b/ < : username > / /foo/"); - // let test_output = vec![ - // (0, "b".to_string(), None), - // (1, "username".to_string(), Some("string".to_string())), - // (2, "age".to_string(), Some("integer".to_string())), - // (3, "foo".to_string(), None), - // ]; assert!(output.is_err()) } @@ -165,9 +166,9 @@ mod tests { let output = super::url_match( "/arpita/foo/28/", &[ - (0, "username".to_string(), Some("string".to_string())), - (1, "foo".to_string(), None), - (2, "age".to_string(), Some("integer".to_string())), + fpm::sitemap::PathParams::named(0, "username".to_string(), "string".to_string()), + fpm::sitemap::PathParams::value(1, "foo".to_string()), + fpm::sitemap::PathParams::named(2, "age".to_string(), "integer".to_string()), ], ); @@ -199,9 +200,9 @@ mod tests { let output = super::url_match( "/arpita/foo/28/", &[ - (0, "username".to_string(), Some("integer".to_string())), - (1, "foo".to_string(), None), - (2, "age".to_string(), Some("integer".to_string())), + fpm::sitemap::PathParams::named(0, "username".to_string(), "integer".to_string()), + fpm::sitemap::PathParams::value(1, "foo".to_string()), + fpm::sitemap::PathParams::named(2, "age".to_string(), "integer".to_string()), ], ); @@ -220,9 +221,9 @@ mod tests { let output = super::url_match( "/arpita/foo/", &[ - (0, "username".to_string(), Some("integer".to_string())), - (1, "foo".to_string(), None), - (2, "age".to_string(), Some("integer".to_string())), + fpm::sitemap::PathParams::named(0, "username".to_string(), "integer".to_string()), + fpm::sitemap::PathParams::value(1, "foo".to_string()), + fpm::sitemap::PathParams::named(2, "age".to_string(), "integer".to_string()), ], ); assert!(!output.unwrap().0) @@ -235,9 +236,9 @@ mod tests { let output = super::url_match( "/b/a/person/", &[ - (0, "b".to_string(), None), - (1, "username".to_string(), Some("string".to_string())), - (2, "person".to_string(), None), + fpm::sitemap::PathParams::value(0, "b".to_string()), + fpm::sitemap::PathParams::named(1, "username".to_string(), "string".to_string()), + fpm::sitemap::PathParams::value(2, "person".to_string()), ], ); let output = output.unwrap(); @@ -261,9 +262,9 @@ mod tests { let output = super::url_match( "/b/a/person/", &[ - (0, "a".to_string(), None), - (1, "username".to_string(), Some("string".to_string())), - (2, "person".to_string(), None), + fpm::sitemap::PathParams::value(0, "a".to_string()), + fpm::sitemap::PathParams::named(1, "username".to_string(), "string".to_string()), + fpm::sitemap::PathParams::value(2, "person".to_string()), ], ); assert!(!output.unwrap().0) @@ -276,10 +277,10 @@ mod tests { let output = super::url_match( "/a/abrark/person/28/", &[ - (0, "a".to_string(), None), - (1, "username".to_string(), Some("string".to_string())), - (2, "person".to_string(), None), - (3, "age".to_string(), Some("integer".to_string())), + fpm::sitemap::PathParams::value(0, "a".to_string()), + fpm::sitemap::PathParams::named(1, "username".to_string(), "string".to_string()), + fpm::sitemap::PathParams::value(2, "person".to_string()), + fpm::sitemap::PathParams::named(3, "age".to_string(), "integer".to_string()), ], ); let output = output.unwrap(); From dce1929f496110887621af19b4e1cb006fcbac7c Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Thu, 5 Jan 2023 14:38:37 +0530 Subject: [PATCH 09/11] fpm/dynamic-urls: clippy happy --- src/sitemap/mod.rs | 2 +- src/sitemap/utils.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sitemap/mod.rs b/src/sitemap/mod.rs index 74a0657c..c3f75035 100644 --- a/src/sitemap/mod.rs +++ b/src/sitemap/mod.rs @@ -49,7 +49,7 @@ pub enum SitemapElement { TocItem(toc::TocItem), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum PathParams { NamedParm { index: usize, diff --git a/src/sitemap/utils.rs b/src/sitemap/utils.rs index a45b54ad..76674e9b 100644 --- a/src/sitemap/utils.rs +++ b/src/sitemap/utils.rs @@ -106,7 +106,7 @@ pub fn parse_path_params( output.push(fpm::sitemap::PathParams::named( index, param_name_part.to_string(), - type_part.to_string(), + type_part.to_string(), // TODO: check the type which are supported in the sitemap )); index += 1; } From 890478a03485f449eb762dbfe17169e5ce2f84c1 Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Thu, 5 Jan 2023 14:45:46 +0530 Subject: [PATCH 10/11] fpm/dynamic-urls: added examples --- examples/dynamic-urls/FPM.ftd | 29 ++++++++++++++++++++++++----- examples/dynamic-urls/bar/b.ftd | 1 + examples/dynamic-urls/foo/a.ftd | 1 + examples/dynamic-urls/index.ftd | 2 +- examples/dynamic-urls/index1.ftd | 1 + 5 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 examples/dynamic-urls/index1.ftd diff --git a/examples/dynamic-urls/FPM.ftd b/examples/dynamic-urls/FPM.ftd index 3ed28120..998d2c4f 100644 --- a/examples/dynamic-urls/FPM.ftd +++ b/examples/dynamic-urls/FPM.ftd @@ -5,15 +5,34 @@ download-base-url: https://www.github.com/ +-- fpm.sitemap: + +# Page 1: /foo/a/ +document: /bar/b/ + + -- fpm.dynamic-urls: -# TOC0 -url: /a//person/ +# TOC00 +url: /a/ < integer : age > /person/ document: index.ftd +## TOC01 +url: /a/ < string : username > /person/ +document: index1.ftd + - TOC1 url: /b//person/ document: index.ftd - - TOC2 - url: /c//person/ - document: index.ftd + +- TOC3 +url: /d/// +document: index.ftd + +- TOC3 +url: /// +document: index1.ftd + +- TOC3 +url: /// +document: index.ftd diff --git a/examples/dynamic-urls/bar/b.ftd b/examples/dynamic-urls/bar/b.ftd index e69de29b..cdf2c149 100644 --- a/examples/dynamic-urls/bar/b.ftd +++ b/examples/dynamic-urls/bar/b.ftd @@ -0,0 +1 @@ +-- ftd.text: I am from bar/b.ftd \ No newline at end of file diff --git a/examples/dynamic-urls/foo/a.ftd b/examples/dynamic-urls/foo/a.ftd index e69de29b..1ab1c1b2 100644 --- a/examples/dynamic-urls/foo/a.ftd +++ b/examples/dynamic-urls/foo/a.ftd @@ -0,0 +1 @@ +-- ftd.text: I am inside the foo/a \ No newline at end of file diff --git a/examples/dynamic-urls/index.ftd b/examples/dynamic-urls/index.ftd index f2a846c8..98799bfb 100644 --- a/examples/dynamic-urls/index.ftd +++ b/examples/dynamic-urls/index.ftd @@ -1 +1 @@ --- ftd.text: Hello world \ No newline at end of file +-- ftd.text: Hello From Index diff --git a/examples/dynamic-urls/index1.ftd b/examples/dynamic-urls/index1.ftd new file mode 100644 index 00000000..75a65b17 --- /dev/null +++ b/examples/dynamic-urls/index1.ftd @@ -0,0 +1 @@ +-- ftd.text: Hello From Index 1 From b85a8032fc7697461cb957c5af305cf7218284e0 Mon Sep 17 00:00:00 2001 From: AbrarNitk Date: Thu, 5 Jan 2023 14:48:05 +0530 Subject: [PATCH 11/11] fpm/dynamic-urls: added more examples for dynamic sitemap --- examples/dynamic-urls/FPM.ftd | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/dynamic-urls/FPM.ftd b/examples/dynamic-urls/FPM.ftd index 998d2c4f..d415b425 100644 --- a/examples/dynamic-urls/FPM.ftd +++ b/examples/dynamic-urls/FPM.ftd @@ -21,10 +21,19 @@ document: index.ftd url: /a/ < string : username > /person/ document: index1.ftd +- TOC1 +url: /b//person/ +document: index.ftd + - TOC1 url: /b//person/ +document: index1.ftd + +- TOC1 +url: /b//person/foo/ document: index.ftd + - TOC3 url: /d/// document: index.ftd