Skip to content

Commit 5956c83

Browse files
committed
feat: Initial release of linkedin-profile-validator
- Format validation for LinkedIn profile URLs - Full validation with network requests - Both sync and async APIs - Comprehensive error handling - Handle LinkedIn's anti-bot protection - Examples and documentation - CI/CD with GitHub Actions - Dual MIT/Apache-2.0 license
1 parent 57db95c commit 5956c83

File tree

12 files changed

+1103
-130
lines changed

12 files changed

+1103
-130
lines changed

.github/workflows/ci.yml

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,80 @@
11
name: CI
22

3-
on: [push, pull_request]
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
RUST_BACKTRACE: 1
412

513
jobs:
614
test:
15+
name: Test
16+
runs-on: ${{ matrix.os }}
17+
strategy:
18+
matrix:
19+
os: [ubuntu-latest, windows-latest, macos-latest]
20+
rust: [stable, beta]
21+
steps:
22+
- uses: actions/checkout@v4
23+
- name: Install Rust
24+
uses: dtolnay/rust-toolchain@master
25+
with:
26+
toolchain: ${{ matrix.rust }}
27+
- name: Cache dependencies
28+
uses: actions/cache@v3
29+
with:
30+
path: |
31+
~/.cargo/registry
32+
~/.cargo/git
33+
target
34+
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
35+
- name: Build
36+
run: cargo build --verbose
37+
- name: Run tests
38+
run: cargo test --verbose
39+
40+
fmt:
41+
name: Rustfmt
742
runs-on: ubuntu-latest
843
steps:
944
- uses: actions/checkout@v4
1045
- uses: dtolnay/rust-toolchain@stable
11-
- name: Build
12-
run: cargo build --all
13-
- name: Clippy
14-
run: cargo clippy --all-targets -- -D warnings
15-
- name: Format
46+
with:
47+
components: rustfmt
48+
- name: Check formatting
1649
run: cargo fmt -- --check
17-
- name: Test
18-
run: cargo test --all
19-
- name: Docker Build
20-
run: docker build -t ${{ github.repository }} .
50+
51+
clippy:
52+
name: Clippy
53+
runs-on: ubuntu-latest
54+
steps:
55+
- uses: actions/checkout@v4
56+
- uses: dtolnay/rust-toolchain@stable
57+
with:
58+
components: clippy
59+
- name: Run clippy
60+
run: cargo clippy -- -D warnings -W clippy::all -W clippy::pedantic -W clippy::nursery -A clippy::module_name_repetitions
61+
62+
doc:
63+
name: Documentation
64+
runs-on: ubuntu-latest
65+
steps:
66+
- uses: actions/checkout@v4
67+
- uses: dtolnay/rust-toolchain@stable
68+
- name: Check documentation
69+
run: cargo doc --no-deps --document-private-items
70+
env:
71+
RUSTDOCFLAGS: -D warnings
72+
73+
publish-dry-run:
74+
name: Publish dry run
75+
runs-on: ubuntu-latest
76+
steps:
77+
- uses: actions/checkout@v4
78+
- uses: dtolnay/rust-toolchain@stable
79+
- name: Cargo publish dry run
80+
run: cargo publish --dry-run

.gitignore

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,49 @@
1-
/target
2-
**/*.rs.bk
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
debug/
4+
target/
5+
6+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
38
Cargo.lock
4-
.DS_Store
9+
10+
# These are backup files generated by rustfmt
11+
**/*.rs.bk
12+
13+
# MSVC Windows builds of rustc generate these, which store debugging information
14+
*.pdb
15+
16+
# RustRover/IntelliJ
17+
.idea/
18+
19+
# VS Code
20+
.vscode/
21+
22+
# MacOS
23+
.DS_Store
24+
25+
# Vim
26+
*.swp
27+
*.swo
28+
*~
29+
30+
# Emacs
31+
*#
32+
.#*
33+
34+
# Testing artifacts
35+
tarpaulin-report.html
36+
cobertura.xml
37+
38+
# Benchmark results
39+
/target/criterion
40+
41+
# Documentation build
42+
/target/doc
43+
44+
# Temporary files
45+
*.tmp
46+
*.temp
47+
48+
# Project specific
549
instruction.md

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [0.1.0] - 2024-01-30
9+
10+
### Added
11+
- Initial release of linkedin-profile-validator
12+
- Format validation for LinkedIn profile URLs without network calls
13+
- Full validation with network requests to check profile existence
14+
- Both synchronous (blocking) and asynchronous APIs
15+
- Comprehensive error handling for different failure scenarios:
16+
- Invalid URL format
17+
- Non-LinkedIn domains
18+
- Non-profile URLs (e.g., company pages)
19+
- Profile not found (404)
20+
- Authentication required (LinkedIn's anti-bot protection)
21+
- Support for handling LinkedIn's rate limiting (status 999)
22+
- Example usage in main.rs
23+
- Comprehensive test suite
24+
25+
### Technical Details
26+
- Built with reqwest for HTTP requests
27+
- Uses regex for URL pattern matching
28+
- Implements proper error types with thiserror
29+
- Supports Rust 2021 edition (minimum Rust 1.70)

CONTRIBUTING.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Contributing to linkedin-profile-validator
2+
3+
First off, thank you for considering contributing to linkedin-profile-validator! It's people like you that make this tool better for everyone.
4+
5+
## Code of Conduct
6+
7+
This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code. Please be respectful and considerate in all interactions.
8+
9+
## How Can I Contribute?
10+
11+
### Reporting Bugs
12+
13+
Before creating bug reports, please check existing issues as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible:
14+
15+
* **Use a clear and descriptive title** for the issue to identify the problem.
16+
* **Describe the exact steps which reproduce the problem** in as many details as possible.
17+
* **Provide specific examples to demonstrate the steps**.
18+
* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
19+
* **Explain which behavior you expected to see instead and why.**
20+
* **Include Rust version** (`rustc --version`).
21+
22+
### Suggesting Enhancements
23+
24+
Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:
25+
26+
* **Use a clear and descriptive title** for the issue to identify the suggestion.
27+
* **Provide a step-by-step description of the suggested enhancement** in as many details as possible.
28+
* **Provide specific examples to demonstrate the steps**.
29+
* **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
30+
* **Explain why this enhancement would be useful** to most users.
31+
32+
### Pull Requests
33+
34+
1. Fork the repo and create your branch from `main`.
35+
2. If you've added code that should be tested, add tests.
36+
3. If you've changed APIs, update the documentation.
37+
4. Ensure the test suite passes (`cargo test`).
38+
5. Make sure your code follows the project style (`cargo fmt` and `cargo clippy`).
39+
6. Issue that pull request!
40+
41+
## Development Process
42+
43+
1. **Setup your development environment:**
44+
```bash
45+
git clone https://github.com/hamzeghalebi/linkedin-profile-validator.git
46+
cd linkedin-profile-validator
47+
cargo build
48+
```
49+
50+
2. **Run tests:**
51+
```bash
52+
cargo test
53+
```
54+
55+
3. **Check formatting and linting:**
56+
```bash
57+
cargo fmt -- --check
58+
cargo clippy -- -D warnings
59+
```
60+
61+
4. **Run the example:**
62+
```bash
63+
cargo run --example basic
64+
```
65+
66+
## Testing Guidelines
67+
68+
* Write tests for any new functionality
69+
* Ensure all tests pass before submitting PR
70+
* Include both positive and negative test cases
71+
* Mock external API calls when possible to avoid rate limiting
72+
73+
## Documentation
74+
75+
* Document all public APIs with doc comments
76+
* Include examples in doc comments where appropriate
77+
* Update README.md if you change how the library is used
78+
* Update CHANGELOG.md following the Keep a Changelog format
79+
80+
## Commit Messages
81+
82+
* Use the present tense ("Add feature" not "Added feature")
83+
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
84+
* Limit the first line to 72 characters or less
85+
* Reference issues and pull requests liberally after the first line
86+
87+
## Questions?
88+
89+
Feel free to open an issue with your question or reach out to the maintainers directly.
90+
91+
Thank you for contributing! 🎉

Cargo.toml

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
[package]
2-
name = "linkdin_url"
2+
name = "linkedin-profile-validator"
33
version = "0.1.0"
44
edition = "2021"
5-
authors = ["Hamze ghalebi@gmail.com"]
5+
rust-version = "1.70"
6+
authors = ["Hamze Ghalebi <hamze.ghalebi@gmail.com>"]
67
license = "MIT OR Apache-2.0"
8+
description = "A Rust library to validate LinkedIn profile URLs by checking format and profile existence"
9+
documentation = "https://docs.rs/linkedin-profile-validator"
10+
homepage = "https://github.com/RustSandbox/linkedin_profile_validator"
11+
repository = "https://github.com/RustSandbox/linkedin_profile_validator"
12+
readme = "README.md"
13+
keywords = ["linkedin", "url", "validation", "profile", "checker"]
14+
categories = ["web-programming", "web-programming::http-client", "parsing"]
15+
exclude = [
16+
".github/*",
17+
".gitignore",
18+
"tests/*",
19+
"benches/*",
20+
]
21+
22+
[lib]
23+
name = "linkedin_profile_validator"
24+
path = "src/lib.rs"
725

826
[dependencies]
9-
anyhow = { version = "1.0.98", features = ["default"] }
10-
clap = { version = "4.5", features = ["derive"] }
11-
env_logger = "0.11"
12-
log = "0.4"
13-
rig-core = { version = "0.12.0" }
14-
schemars = "0.9.0"
15-
serde = { version = "1.0.219", features = ["derive"] }
16-
tokio = { version = "1.45.1", features = ["full"] }
17-
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
27+
reqwest = { version = "0.12", features = ["blocking", "rustls-tls"] }
28+
url = "2.5"
29+
regex = "1.11"
30+
thiserror = "2.0"
31+
tokio = { version = "1.45.1", features = ["rt-multi-thread", "macros"] }
1832

1933
[dev-dependencies]
2034
pretty_assertions = "1.4"

0 commit comments

Comments
 (0)