# scantarget — Target parsing and expansion
[](https://opensource.org/licenses/MIT) [](https://img.shields.io/badge/tests-39%20passing-brightgreen.svg) [](https://crates.io/crates/scantarget)
## Why
Scanning workflows fail when target input is inconsistent (`https://`, plain domain, IP, CIDR, mixed formats). `scantarget` standardizes target ingestion and normalization so scanners process a stable target model instead of parsing strings repeatedly.
It gives you parse utilities, list loaders, and CIDR expansion in one place, reducing scanner-specific parsing bugs and input edge-case drift.
## Quick Start
```rust
use scantarget::{parse, parse_many, Target, TargetList, TargetListError};
fn main() -> Result<(), TargetListError> {
let one = parse("https://example.com")
.expect("valid target");
let many = parse_many("example.org,10.0.0.1/30");
let mut list = TargetList {
targets: TargetList::parse_str("https://example.com,203.0.113.10"),
};
for t in &many {
println!("{}", t);
}
list.targets.push(one);
Ok(())
}
```
## Features
- Parse URLs, domains, IPs, and CIDR values with strong validation.
- `TargetList` and `TargetListError` for ingest workflows.
- Expand CIDR ranges into concrete targets.
- Parse from args, strings, files, and stdin.
- Optional trait adapter with `TargetSource`.
## TOML Configuration
`scantarget` supports TOML target lists in this shape:
```toml
targets = ["https://example.com", "example.org", "203.0.113.0/30"]
```
```rust
use scantarget::TargetList;
let targets = TargetList::from_toml(
r#"targets = ["https://example.com", "example.org"]"#
).unwrap();
```
## API Overview
- `Target` enum: `Url`, `Domain`, `Ip`, `Cidr`.
- `TargetParseError`: parse error model.
- `parse`, `parse_many`: convenience parsing helpers.
- `TargetList` / `TargetListError`: grouped targets and loaders.
- `expand_cidr`, `expand_all`: CIDR expansion helpers.
- `TargetSource`: trait for custom target providers.
## Examples
### 1) Parse mixed user input
```rust
use scantarget::parse_many;
let targets = parse_many("https://api.internal:8443,example.test,198.51.100.0/31");
assert_eq!(targets.len(), 3);
```
### 2) Expand CIDR before dispatch
```rust
use scantarget::{expand_all, parse, Target};
let cidr = parse("10.0.0.0/30").unwrap();
let expanded = expand_all(&[cidr]);
for t in expanded {
println!("{}", t);
}
```
### 3) Implement `TargetSource` for a custom feed
```rust
use scantarget::{Target, TargetSource};
struct QueueSource {
items: Vec<Target>,
}
impl TargetSource for QueueSource {
fn targets(&self) -> Vec<Target> {
self.items.clone()
}
fn count(&self) -> usize {
self.items.len()
}
}
```
## Traits
`scantarget` defines `TargetSource` when you need to feed scanner targets from a queue, API, or custom database instead of CLI/file text.
## Related Crates
- [scanclient](https://docs.rs/scanclient)
- [scanstate](https://docs.rs/scanstate)
- [codewalk](https://docs.rs/codewalk)
## License
MIT, Corum Collective LLC
Docs: https://docs.rs/scantarget
Santh ecosystem: https://santh.io