Skip to content

Commit 38c4b87

Browse files
authored
chore: release v0.3.0 (#29)
* docs: update READMEs with benchmark results and Syndication namespace - Add detailed benchmark tables (10.7µs small, 93.6µs medium, 939µs large) - Add Python feedparser comparison (90-94x speedup) - Add Syndication namespace to supported extensions - Update test coverage from 83% to 91% - Add performance tips for Python and Node.js bindings * chore: release v0.3.0 - Syndication Module namespace support - feed.published, xml:base, xml:lang, license fields - Python and Node.js bindings updates - Benchmark results in READMEs - Test coverage improved to 91%+
1 parent ea0cd24 commit 38c4b87

File tree

11 files changed

+103
-23
lines changed

11 files changed

+103
-23
lines changed

CHANGELOG.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.3.0] - 2025-12-18
11+
12+
### Added
13+
- Syndication Module namespace support (`syn:updatePeriod`, `syn:updateFrequency`, `syn:updateBase`)
14+
- `feed.published` field for Atom feeds and RSS channel `pubDate`
15+
- `xml:base` URL resolution for relative URLs in Atom and RSS feeds
16+
- `xml:lang` attribute tracking for feed and entry language detection
17+
- Creative Commons `license` field extraction from `rel="license"` links
18+
- Comprehensive RSS 1.0 integration tests (12+ test cases)
19+
- Syndication metadata exposed in Python and Node.js bindings
20+
- Dublin Core fields (`dc_creator`, `dc_publisher`, `dc_rights`) in bindings
21+
- Benchmark results in all README files
22+
23+
### Changed
24+
- Improved test coverage from 83% to 91%+
25+
- Optimized Python bindings to return `&str` instead of `String` for enum values
26+
- Simplified Node.js Entry conversion using idiomatic `.collect()` pattern
27+
- Updated documentation with performance benchmarks (90-94x faster than Python feedparser)
28+
29+
### Fixed
30+
- Performance issue with unnecessary string allocations in Python `__repr__` methods
31+
1032
## [0.2.1] - 2025-12-16
1133

1234
### Changed
@@ -125,7 +147,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
125147
- Comprehensive test coverage
126148
- Documentation with examples
127149

128-
[Unreleased]: https://github.com/bug-ops/feedparser-rs/compare/v0.2.1...HEAD
150+
[Unreleased]: https://github.com/bug-ops/feedparser-rs/compare/v0.3.0...HEAD
151+
[0.3.0]: https://github.com/bug-ops/feedparser-rs/compare/v0.2.1...v0.3.0
129152
[0.2.1]: https://github.com/bug-ops/feedparser-rs/compare/v0.2.0...v0.2.1
130153
[0.2.0]: https://github.com/bug-ops/feedparser-rs/compare/v0.1.8...v0.2.0
131154
[0.1.8]: https://github.com/bug-ops/feedparser-rs/compare/v0.1.7...v0.1.8

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ members = [
77
resolver = "2"
88

99
[workspace.package]
10-
version = "0.2.1"
10+
version = "0.3.0"
1111
edition = "2024"
1212
rust-version = "1.88.0"
1313
authors = ["bug-ops"]

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ High-performance RSS/Atom/JSON Feed parser written in Rust, with Python and Node
3737
| Media RSS | Media attachments and metadata |
3838
| iTunes | Podcast metadata (author, duration, explicit) |
3939
| Podcast 2.0 | Chapters, transcripts, funding |
40+
| Syndication | Update schedule (period, frequency, base) |
4041
| GeoRSS | Geographic location data (point, line, polygon, box) |
4142
| Creative Commons | License information with `rel="license"` links |
4243

@@ -203,11 +204,25 @@ cargo make --list-all-steps
203204

204205
## Benchmarks
205206

206-
Run benchmark comparison against Python feedparser:
207+
Measured on Apple M1 Pro, parsing real-world RSS feeds:
207208

208-
```bash
209-
cargo make bench-compare
210-
```
209+
| Feed Size | Time | Throughput |
210+
|-----------|------|------------|
211+
| Small (2 KB) | **10.7 µs** | 187 MB/s |
212+
| Medium (20 KB) | **93.6 µs** | 214 MB/s |
213+
| Large (200 KB) | **939 µs** | 213 MB/s |
214+
215+
Format detection: **128 ns** (near-instant)
216+
217+
### vs Python feedparser
218+
219+
| Operation | feedparser-rs | Python feedparser | Speedup |
220+
|-----------|---------------|-------------------|---------|
221+
| Parse 20 KB RSS | 0.09 ms | 8.5 ms | **94x** |
222+
| Parse 200 KB RSS | 0.94 ms | 85 ms | **90x** |
223+
224+
> [!TIP]
225+
> Run your own benchmarks with `cargo bench` or compare against Python with `cargo make bench-compare`.
211226
212227
## MSRV Policy
213228

crates/feedparser-rs-core/README.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ This is the core parsing library that powers the Python and Node.js bindings.
1313

1414
- **Multi-format**: RSS 0.9x/1.0/2.0, Atom 0.3/1.0, JSON Feed 1.0/1.1
1515
- **Tolerant**: Bozo flag for graceful handling of malformed feeds
16-
- **Fast**: Native Rust performance
16+
- **Fast**: Native Rust performance (200+ MB/s throughput)
1717
- **Safe**: No unsafe code, comprehensive error handling
1818
- **HTTP support**: Fetch feeds from URLs with compression and conditional GET
1919
- **Podcast support**: iTunes and Podcast 2.0 namespace extensions
20-
- **Namespace extensions**: Dublin Core, Media RSS, GeoRSS, Creative Commons
21-
- **Well-tested**: 83%+ test coverage with real-world feed fixtures
20+
- **Namespace extensions**: Dublin Core, Media RSS, Syndication, GeoRSS, Creative Commons
21+
- **Well-tested**: 91%+ test coverage with real-world feed fixtures
2222

2323
## Installation
2424

@@ -138,6 +138,24 @@ let feed = parse_with_limits(xml.as_bytes(), limits)?;
138138
> [!NOTE]
139139
> Default limits are generous for typical feeds. Use `ParserLimits::strict()` for untrusted input.
140140
141+
## Benchmarks
142+
143+
Measured on Apple M1 Pro:
144+
145+
| Feed Size | Time | Throughput |
146+
|-----------|------|------------|
147+
| Small (2 KB) | 10.7 µs | 187 MB/s |
148+
| Medium (20 KB) | 93.6 µs | 214 MB/s |
149+
| Large (200 KB) | 939 µs | 213 MB/s |
150+
151+
Format detection: 128 ns
152+
153+
Run benchmarks:
154+
155+
```bash
156+
cargo bench
157+
```
158+
141159
## Platform Bindings
142160

143161
- **Node.js**: [`feedparser-rs`](https://www.npmjs.com/package/feedparser-rs) on npm

crates/feedparser-rs-node/README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,23 @@ if (entry.published) {
202202

203203
## Performance
204204

205-
Benchmarks vs Python feedparser (parsing 100KB RSS feed):
205+
Benchmarks on Apple M1 Pro:
206206

207-
| Library | Time | Speedup |
208-
|---------|------|---------|
209-
| feedparser-rs | 0.5ms | 100x |
210-
| feedparser (Python) | 50ms | 1x |
207+
| Feed Size | Time | Throughput |
208+
|-----------|------|------------|
209+
| Small (2 KB) | 0.01 ms | 187 MB/s |
210+
| Medium (20 KB) | 0.09 ms | 214 MB/s |
211+
| Large (200 KB) | 0.94 ms | 213 MB/s |
212+
213+
### vs Python feedparser
214+
215+
| Operation | feedparser-rs | Python feedparser | Speedup |
216+
|-----------|---------------|-------------------|---------|
217+
| Parse 20 KB RSS | 0.09 ms | 8.5 ms | **94x** |
218+
| Parse 200 KB RSS | 0.94 ms | 85 ms | **90x** |
219+
220+
> [!TIP]
221+
> For best performance, pass `Buffer` instead of `string` to avoid UTF-8 conversion overhead.
211222
212223
## Platform Support
213224

crates/feedparser-rs-node/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/feedparser-rs-node/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "feedparser-rs",
3-
"version": "0.2.1",
3+
"version": "0.3.0",
44
"description": "High-performance RSS/Atom/JSON Feed parser for Node.js",
55
"main": "index.js",
66
"types": "index.d.ts",
@@ -47,4 +47,4 @@
4747
"@napi-rs/cli": "^3.5",
4848
"c8": "^10.1.3"
4949
}
50-
}
50+
}

crates/feedparser-rs-py/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "feedparser-rs-py"
3-
version = "0.1.0"
3+
version.workspace = true
44
edition = "2024"
55
rust-version = "1.85"
66
license = "MIT OR Apache-2.0"

crates/feedparser-rs-py/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,19 @@ for entry in d.entries:
149149

150150
- `ParserLimits` — Resource limits configuration
151151

152+
## Performance
153+
154+
Benchmarks vs Python feedparser on Apple M1 Pro:
155+
156+
| Operation | feedparser-rs | Python feedparser | Speedup |
157+
|-----------|---------------|-------------------|---------|
158+
| Parse 2 KB RSS | 0.01 ms | 0.9 ms | **90x** |
159+
| Parse 20 KB RSS | 0.09 ms | 8.5 ms | **94x** |
160+
| Parse 200 KB RSS | 0.94 ms | 85 ms | **90x** |
161+
162+
> [!TIP]
163+
> For maximum performance, pass `bytes` instead of `str` to avoid UTF-8 re-encoding.
164+
152165
## Platform Support
153166

154167
Pre-built wheels available for:

0 commit comments

Comments
 (0)