headless_lms_utils/
course_url.rs1use url::Url;
2
3pub fn build_course_url(base_url: &str, org_slug: &str, course_slug: &str) -> String {
4 format!(
5 "{}/org/{}/courses/{}",
6 base_url.trim_end_matches('/'),
7 org_slug,
8 course_slug,
9 )
10}
11
12pub fn build_courses_base_url(base_url: &str, org_slug: &str) -> String {
13 format!(
14 "{}/org/{}/courses",
15 base_url.trim_end_matches('/'),
16 org_slug,
17 )
18}
19
20pub fn course_page_url(
22 base_url: &str,
23 organization_slug: &str,
24 course_slug: &str,
25 page_url_path: &str,
26) -> Option<String> {
27 let mut url = Url::parse(base_url).ok()?;
28 url.set_path(&format!(
30 "/org/{organization_slug}/courses/{course_slug}{page_url_path}"
31 ));
32 Some(url.to_string())
33}
34
35#[derive(Debug, PartialEq, Eq)]
37pub struct CoursePageRef {
38 pub course_slug: String,
39 pub page_url_path: Option<String>,
41}
42
43#[derive(Debug, PartialEq, Eq)]
45pub enum CourseUrlError {
46 InvalidBaseUrl,
48 OtherSite,
50 NotACourseUrl,
52}
53
54pub fn parse_course_page_url(base_url: &str, url: &str) -> Result<CoursePageRef, CourseUrlError> {
57 let base = Url::parse(base_url).map_err(|_| CourseUrlError::InvalidBaseUrl)?;
58 let parsed = Url::parse(url).map_err(|_| CourseUrlError::NotACourseUrl)?;
59 if parsed.origin() != base.origin() {
60 return Err(CourseUrlError::OtherSite);
61 }
62 let segments: Vec<&str> = parsed
63 .path_segments()
64 .ok_or(CourseUrlError::NotACourseUrl)?
65 .filter(|segment| !segment.is_empty())
66 .collect();
67 match segments.as_slice() {
68 ["org", _, "courses", course, page @ ..] => Ok(CoursePageRef {
69 course_slug: course.to_string(),
70 page_url_path: (!page.is_empty()).then(|| format!("/{}", page.join("/"))),
71 }),
72 _ => Err(CourseUrlError::NotACourseUrl),
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn course_page_url_percent_encodes_the_stored_path() {
82 assert_eq!(
83 course_page_url(
84 "https://courses.mooc.fi",
85 "uh-cs",
86 "java",
87 "/chapter-1/tehtävä"
88 )
89 .as_deref(),
90 Some("https://courses.mooc.fi/org/uh-cs/courses/java/chapter-1/teht%C3%A4v%C3%A4")
91 );
92 }
93
94 #[test]
95 fn course_page_url_needs_a_valid_base_url() {
96 assert_eq!(course_page_url("not a url", "org", "course", "/"), None);
97 }
98}