diff --git a/examples/collect_links/collect_links.rs b/examples/collect_links/collect_links.rs
index 57edd5f..9299c94 100644
--- a/examples/collect_links/collect_links.rs
+++ b/examples/collect_links/collect_links.rs
@@ -7,18 +7,10 @@ use tokio_stream::StreamExt;
async fn main() -> Result<()> {
// Collect all links from the following inputs
let inputs = vec![
- Input {
- source: InputSource::RemoteUrl(Box::new(
- Url::parse("https://github.com/lycheeverse/lychee").unwrap(),
- )),
- file_type_hint: None,
- excluded_paths: None,
- },
- Input {
- source: InputSource::FsPath(PathBuf::from("fixtures/TEST.md")),
- file_type_hint: None,
- excluded_paths: None,
- },
+ Input::from_input_source(InputSource::RemoteUrl(Box::new(
+ Url::parse("https://github.com/lycheeverse/lychee").unwrap(),
+ ))),
+ Input::from_input_source(InputSource::FsPath(PathBuf::from("fixtures/TEST.md"))),
];
let links = Collector::default()
diff --git a/lychee-bin/src/options.rs b/lychee-bin/src/options.rs
index 924d0c7..e53639f 100644
--- a/lychee-bin/src/options.rs
+++ b/lychee-bin/src/options.rs
@@ -331,15 +331,16 @@ impl LycheeOptions {
// accept a `Vec` in `LycheeOptions` and do the conversion there, but
// we wouldn't get access to `glob_ignore_case`.
pub(crate) fn inputs(&self) -> Result> {
- let excluded = if self.config.exclude_path.is_empty() {
- None
- } else {
- Some(self.config.exclude_path.clone())
- };
-
self.raw_inputs
.iter()
- .map(|s| Input::new(s, None, self.config.glob_ignore_case, excluded.clone()))
+ .map(|s| {
+ Input::new(
+ s,
+ None,
+ self.config.glob_ignore_case,
+ self.config.exclude_path.clone(),
+ )
+ })
.collect::>()
.context("Cannot parse inputs from arguments")
}
diff --git a/lychee-lib/src/collector.rs b/lychee-lib/src/collector.rs
index 8ce6861..c3db7ff 100644
--- a/lychee-lib/src/collector.rs
+++ b/lychee-lib/src/collector.rs
@@ -274,7 +274,12 @@ mod tests {
// Treat as plaintext file (no extension)
let file_path = temp_dir.path().join("README");
let _file = File::create(&file_path).unwrap();
- let input = Input::new(&file_path.as_path().display().to_string(), None, true, None)?;
+ let input = Input::new(
+ &file_path.as_path().display().to_string(),
+ None,
+ true,
+ vec![],
+ )?;
let contents: Vec<_> = input
.get_contents(
true,
@@ -293,7 +298,7 @@ mod tests {
#[tokio::test]
async fn test_url_without_extension_is_html() -> Result<()> {
- let input = Input::new("https://example.com/", None, true, None)?;
+ let input = Input::new("https://example.com/", None, true, vec![])?;
let contents: Vec<_> = input
.get_contents(
true,
@@ -330,33 +335,17 @@ mod tests {
let mock_server = mock_server!(StatusCode::OK, set_body_string(TEST_URL));
let inputs = vec![
- Input {
- source: InputSource::String(TEST_STRING.to_owned()),
- file_type_hint: None,
- excluded_paths: None,
- },
- Input {
- source: InputSource::RemoteUrl(Box::new(
- Url::parse(&mock_server.uri())
- .map_err(|e| (mock_server.uri(), e))
- .unwrap(),
- )),
- file_type_hint: None,
- excluded_paths: None,
- },
- Input {
- source: InputSource::FsPath(file_path),
- file_type_hint: None,
- excluded_paths: None,
- },
- Input {
- source: InputSource::FsGlob {
- pattern: temp_dir_path.join("glob*").to_str().unwrap().to_owned(),
- ignore_case: true,
- },
- file_type_hint: None,
- excluded_paths: None,
- },
+ Input::from_input_source(InputSource::String(TEST_STRING.to_owned())),
+ Input::from_input_source(InputSource::RemoteUrl(Box::new(
+ Url::parse(&mock_server.uri())
+ .map_err(|e| (mock_server.uri(), e))
+ .unwrap(),
+ ))),
+ Input::from_input_source(InputSource::FsPath(file_path)),
+ Input::from_input_source(InputSource::FsGlob {
+ pattern: temp_dir_path.join("glob*").to_str().unwrap().to_owned(),
+ ignore_case: true,
+ }),
];
let links = collect_verbatim(inputs, None, None, FileType::default_extensions())
@@ -383,7 +372,7 @@ mod tests {
let input = Input {
source: InputSource::String("This is [a test](https://endler.dev). This is a relative link test [Relative Link Test](relative_link)".to_string()),
file_type_hint: Some(FileType::Markdown),
- excluded_paths: None,
+ excluded_paths: vec![],
};
let links = collect(vec![input], None, Some(base)).await.ok().unwrap();
@@ -409,7 +398,7 @@ mod tests {
.to_string(),
),
file_type_hint: Some(FileType::Html),
- excluded_paths: None,
+ excluded_paths: vec![],
};
let links = collect(vec![input], None, Some(base)).await.ok().unwrap();
@@ -438,7 +427,7 @@ mod tests {
.to_string(),
),
file_type_hint: Some(FileType::Html),
- excluded_paths: None,
+ excluded_paths: vec![],
};
let links = collect(vec![input], None, Some(base)).await.ok().unwrap();
@@ -464,7 +453,7 @@ mod tests {
.to_string(),
),
file_type_hint: Some(FileType::Markdown),
- excluded_paths: None,
+ excluded_paths: vec![],
};
let links = collect(vec![input], None, Some(base)).await.ok().unwrap();
@@ -487,7 +476,7 @@ mod tests {
let input = Input {
source: InputSource::String(input),
file_type_hint: Some(FileType::Html),
- excluded_paths: None,
+ excluded_paths: vec![],
};
let links = collect(vec![input], None, Some(base)).await.ok().unwrap();
@@ -516,11 +505,7 @@ mod tests {
let server_uri = Url::parse(&mock_server.uri()).unwrap();
- let input = Input {
- source: InputSource::RemoteUrl(Box::new(server_uri.clone())),
- file_type_hint: None,
- excluded_paths: None,
- };
+ let input = Input::from_input_source(InputSource::RemoteUrl(Box::new(server_uri.clone())));
let links = collect(vec![input], None, None).await.ok().unwrap();
@@ -534,13 +519,10 @@ mod tests {
#[tokio::test]
async fn test_email_with_query_params() {
- let input = Input {
- source: InputSource::String(
- "This is a mailto:user@example.com?subject=Hello link".to_string(),
- ),
- file_type_hint: None,
- excluded_paths: None,
- };
+ let input = Input::from_input_source(InputSource::String(
+ "This is a mailto:user@example.com?subject=Hello link".to_string(),
+ ));
+
let links = collect(vec![input], None, None).await.ok().unwrap();
let expected_links = HashSet::from_iter([mail("user@example.com")]);
@@ -569,7 +551,7 @@ mod tests {
.unwrap(),
)),
file_type_hint: Some(FileType::Html),
- excluded_paths: None,
+ excluded_paths: vec![],
},
Input {
source: InputSource::RemoteUrl(Box::new(
@@ -580,7 +562,7 @@ mod tests {
.unwrap(),
)),
file_type_hint: Some(FileType::Html),
- excluded_paths: None,
+ excluded_paths: vec![],
},
];
@@ -615,7 +597,7 @@ mod tests {
.into(),
),
file_type_hint: Some(FileType::Html),
- excluded_paths: None,
+ excluded_paths: vec![],
};
let links = collect(vec![input], None, Some(base)).await.ok().unwrap();
diff --git a/lychee-lib/src/types/input.rs b/lychee-lib/src/types/input.rs
index 6665085..42ea761 100644
--- a/lychee-lib/src/types/input.rs
+++ b/lychee-lib/src/types/input.rs
@@ -108,7 +108,7 @@ pub struct Input {
/// Hint to indicate which extractor to use
pub file_type_hint: Option,
/// Excluded paths that will be skipped when reading content
- pub excluded_paths: Option>,
+ pub excluded_paths: Vec,
}
impl Input {
@@ -124,7 +124,7 @@ impl Input {
value: &str,
file_type_hint: Option,
glob_ignore_case: bool,
- excluded_paths: Option>,
+ excluded_paths: Vec,
) -> Result {
let source = if value == STDIN {
InputSource::Stdin
@@ -200,7 +200,16 @@ impl Input {
/// Returns an error if the input does not exist (i.e. invalid path)
/// and the input cannot be parsed as a URL.
pub fn from_value(value: &str) -> Result {
- Self::new(value, None, false, None)
+ Self::new(value, None, false, vec![])
+ }
+
+ /// Convenience constructor
+ pub fn from_input_source(source: InputSource) -> Self {
+ Self {
+ source,
+ file_type_hint: None,
+ excluded_paths: vec![],
+ }
}
/// Retrieve the contents from the input
@@ -360,10 +369,7 @@ impl Input {
/// Check if the given path was excluded from link checking
fn is_excluded_path(&self, path: &PathBuf) -> bool {
- let Some(excluded_paths) = &self.excluded_paths else {
- return false;
- };
- is_excluded_path(excluded_paths, path)
+ is_excluded_path(&self.excluded_paths, path)
}
/// Get the input content of a given path
@@ -437,15 +443,15 @@ mod tests {
assert!(path.exists());
assert!(path.is_relative());
- let input = Input::new(test_file, None, false, None);
+ let input = Input::new(test_file, None, false, vec![]);
assert!(input.is_ok());
assert!(matches!(
input,
Ok(Input {
source: InputSource::FsPath(PathBuf { .. }),
file_type_hint: None,
- excluded_paths: None,
- })
+ excluded_paths
+ }) if excluded_paths.is_empty()
));
}