fix: change JSON-RPC request ID type from u32 to i64 (#416)

The JSON-RPC 2.0 specification allows the ID field to be any JSON number,
including negative integers and large values. The previous u32 implementation
was limited to 0-4,294,967,295 and couldn't handle negative IDs.

Changes:
- Changed NumberOrString::Number from u32 to i64 to support full JSON number range
- Updated deserializer to handle both signed and unsigned integers
- Modified AtomicU32Provider to use AtomicU64 internally with i64 conversion
- Fixed progress token handling in meta.rs for i64 values
- Added comprehensive test for negative and large request IDs

This ensures full compliance with the JSON-RPC 2.0 specification.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
David Soria Parra 2025-09-04 20:22:44 +01:00 • committed by GitHub
commit 9105ba7963
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -193,7 +193,7 @@ impl<R: ServiceRole, S: Service<R>> DynService<R> for S {
use std::{
collections::{HashMap, VecDeque},
ops::Deref,
sync::{Arc, atomic::AtomicU32},
sync::{Arc, atomic::AtomicU64},
time::Duration,
};
@ -212,20 +212,21 @@ pub type AtomicU32ProgressTokenProvider = AtomicU32Provider;
#[derive(Debug, Default)]
pub struct AtomicU32Provider {
id: AtomicU32,
id: AtomicU64,
}
impl RequestIdProvider for AtomicU32Provider {
fn next_request_id(&self) -> RequestId {
RequestId::Number(self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst))
let id = self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
// Safe conversion: we start at 0 and increment by 1, so we won't overflow i64::MAX in practice
RequestId::Number(id as i64)
}
}
impl ProgressTokenProvider for AtomicU32Provider {
fn next_progress_token(&self) -> ProgressToken {
ProgressToken(NumberOrString::Number(
self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst),
))
let id = self.id.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
ProgressToken(NumberOrString::Number(id as i64))
}
}