# Contributing to schemaorg-rs
Thank you for your interest in contributing. This guide covers the
development setup, code standards, and how to add new features.
## Development Setup
### Prerequisites
- Rust 1.75+ (`rustup default stable`)
- `wasm-pack` (for WASM builds): `cargo install wasm-pack`
- Node.js 18+ (for WASM/npm testing)
### Clone and build
```bash
git clone https://github.com/mitrovicsinisaa/schemaorg-rs
cd schemaorg-rs
cargo build --features full
cargo test --features full
```
### Feature combinations to test
```bash
cargo test --no-default-features # core types only
cargo test --features extraction # extraction layer
cargo test --features "extraction,validation" # + validation
cargo test --features full # extraction + validation + profiles
cargo test --features cli # full + CLI
```
## Code Standards
### Rust conventions
- **No `unwrap()` outside tests.** Use `thiserror` for library errors.
- **`#[must_use]`** on all public functions that return values.
- **`#[non_exhaustive]`** on all public enums.
- **Doc comments** on all public items with `# Examples` and `# Errors` sections.
- **ASCII-only source.** No Unicode in doc comments or string literals
(use `\u{xxxx}` escapes where needed).
- Run `cargo clippy --all-features -- -D warnings` before submitting.
- Run `cargo fmt` for consistent formatting.
### Testing
- Table-driven tests where applicable.
- Integration tests in `tests/` directory.
- Doc tests for all public API examples.
- CLI tests via `std::process::Command`.
## Adding a New Profile
1. Create `src/profiles/google/your_type.rs`
2. Implement the `Profile` trait
3. Register it in `src/profiles/google/mod.rs` via `register_all()`
4. Add tests in `tests/profile_tests.rs`
5. Add documentation in `docs/profiles/your_type.md`
6. Update `docs/profiles/README.md`
### Profile template
```rust
use crate::profiles::{Profile, NodeProfileResult, TypeEligibility};
use crate::profiles::google::common;
use crate::types::SchemaNode;
use crate::validation::ValidationDiagnostic;
pub struct GoogleYourTypeProfile;
impl Profile for GoogleYourTypeProfile {
fn name(&self) -> &'static str { "google" }
fn version(&self) -> &'static str { "2024-01-01" }
fn source_url(&self) -> &'static str {
"https://developers.google.com/search/docs/appearance/structured-data/your-type"
}
fn supported_types(&self) -> &[&str] { &["YourType"] }
fn evaluate_node(
&self,
node: &SchemaNode,
_vocab_diagnostics: &[ValidationDiagnostic],
) -> NodeProfileResult {
let mut required_missing = Vec::new();
let mut recommended_missing = Vec::new();
let mut diagnostics = Vec::new();
// Check required fields
common::check_required(node, "name", &mut required_missing, &mut diagnostics);
// Check recommended fields
common::check_recommended(node, "description", &mut recommended_missing, &mut diagnostics);
NodeProfileResult {
type_eligibility: TypeEligibility {
schema_type: "YourType".to_string(),
eligible: required_missing.is_empty(),
required_missing,
recommended_missing,
field_diagnostics: diagnostics,
},
}
}
}
```
## Updating the Schema.org Vocabulary
1. Download the latest vocabulary:
```bash
curl -o schema-data/schemaorg-all-https.jsonld \
https://schema.org/version/latest/schemaorg-all-https.jsonld
```
2. Run `cargo build` -- the `build.rs` pipeline will regenerate the lookups.
3. Run `cargo test --features full` to verify.
4. Update the version reference in `vocabulary/mod.rs` if needed.
## Pull Request Process
1. Fork the repository and create a feature branch.
2. Write tests for your changes.
3. Ensure all tests pass: `cargo test --features cli`
4. Ensure clippy is clean: `cargo clippy --all-features -- -D warnings`
5. Ensure formatting: `cargo fmt -- --check`
6. Update documentation if adding public API.
7. Submit a PR with a clear description.
## License
All contributions are licensed under the MIT license.
See [LICENSE](LICENSE) for details.