diff --git a/Makefile b/Makefile index 61f722f..21a1545 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ clean: rm -rf target test: - cargo test + cargo test -- --nocapture valid: cargo fmt --all @@ -17,4 +17,7 @@ check: cargo fmt --all -- --check cargo clippy --all-targets --all-features -- -D warnings -.PHONY: build-fst clean test valid check \ No newline at end of file +doc: + cargo doc --open + +.PHONY: build-fst clean test valid check doc \ No newline at end of file diff --git a/fst_builder/main.rs b/fst_builder/main.rs index c65ef7c..ccbd861 100644 --- a/fst_builder/main.rs +++ b/fst_builder/main.rs @@ -1,3 +1,14 @@ +/* + +Copyright (c) nexB Inc. and others. All rights reserved. +ScanCode is a trademark of nexB Inc. +SPDX-License-Identifier: Apache-2.0 +See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +See https://github.com/aboutcode-org/purl-validator-rust for support or download. +See https://aboutcode.org for more information about nexB OSS projects. + +*/ + use fst::SetBuilder; use std::fs::File; use std::io::{BufRead, BufReader}; diff --git a/src/lib.rs b/src/lib.rs index 83fc069..bb48e90 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,33 @@ +/* + +Copyright (c) nexB Inc. and others. All rights reserved. +ScanCode is a trademark of nexB Inc. +SPDX-License-Identifier: Apache-2.0 +See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +See https://github.com/aboutcode-org/purl-validator-rust for support or download. +See https://aboutcode.org for more information about nexB OSS projects. + +*/ + +//! A library to validate whether a PURL actually exists. +//! +//! **purl-validator** is a Rust library for validating +//! [`Package URLs` (PURLs)](https://github.com/package-url/purl-spec). +//! It works fully offline, including in **air-gapped** or **restricted environments**, +//! and answers one key question: **Does the package this PURL represents actually exist?** +//! +//! +//! # Examples +//! +//! Simplest way to use `validate` is as follows: +//! +//! ``` +//! use purl_validator::validate; +//! +//! let result: bool = validate("pkg:nuget/FluentValidation"); +//! ``` +//! + use fst::Set; use memmap2::Mmap; use once_cell::sync::Lazy; @@ -16,9 +46,20 @@ fn load_fst(path: &Path) -> Set { Set::new(mmap).expect("Failed to load FST from mmap") } -pub fn validate(packageurl: &str) -> bool { +fn strip_and_check_purl(packageurl: &str, fst_map: &Set) -> bool { let trimmed_packageurl = packageurl.trim_end_matches("/"); - VALIDATOR.contains(trimmed_packageurl) + fst_map.contains(trimmed_packageurl) +} + +/// Validate a Package URL (PURL) +/// +/// Returns `true` if the given base PURL represents an existing package, +/// otherwise returns `false`. +/// +/// Use pre-built FST (Finite State Transducer) to perform lookups and confirm whether +/// the **base PURL** exists. +pub fn validate(packageurl: &str) -> bool { + strip_and_check_purl(packageurl, &VALIDATOR) } #[cfg(test)] diff --git a/src/validate_tests.rs b/src/validate_tests.rs index dff38d4..5f00f91 100644 --- a/src/validate_tests.rs +++ b/src/validate_tests.rs @@ -1,3 +1,14 @@ +/* + +Copyright (c) nexB Inc. and others. All rights reserved. +ScanCode is a trademark of nexB Inc. +SPDX-License-Identifier: Apache-2.0 +See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +See https://github.com/aboutcode-org/purl-validator-rust for support or download. +See https://aboutcode.org for more information about nexB OSS projects. + +*/ + use super::*; use std::path::Path; @@ -6,6 +17,21 @@ fn test_validate_with_custom_file() { let test_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/test_purls.fst"); let validator = load_fst(&test_path); + assert!(strip_and_check_purl( + "pkg:nuget/FluentUtils.EnumExtensions", + &validator + )); + assert!(!strip_and_check_purl("pkg:example/nonexistent", &validator)); +} + +#[test] +fn test_validate_with_packageurl_trailing_slash() { + let test_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/test_purls.fst"); + let validator = load_fst(&test_path); + assert!(validator.contains("pkg:nuget/FluentUtils.EnumExtensions")); - assert!(!validator.contains("pkg:example/nonexistent")); + assert!(strip_and_check_purl( + "pkg:nuget/FluentUtils.EnumExtensions/", + &validator + )); }