Skip to content

Commit 033d631

Browse files
committed
lazy utf-8 validation
Makes text::Reader a wrapper around &[u8] and defers utf-8 validation until `to_str()` or `to_string()` is called. This means that users will only need to pay the utf8 validation cost if they actually need it. This also allows users to access (broken) non-utf8 Text data. Previously such data was inaccessible.
1 parent a8a44da commit 033d631

File tree

21 files changed

+361
-202
lines changed

21 files changed

+361
-202
lines changed

benchmark/carsales.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ const MAKES: [&str; 5] = ["Toyota", "GM", "Ford", "Honda", "Tesla"];
8282
const MODELS: [&str; 6] = ["Camry", "Prius", "Volt", "Accord", "Leaf", "Model S"];
8383

8484
pub fn random_car(rng: &mut FastRand, mut car: car::Builder) {
85-
car.set_make(MAKES[rng.next_less_than(MAKES.len() as u32) as usize]);
86-
car.set_model(MODELS[rng.next_less_than(MODELS.len() as u32) as usize]);
85+
car.set_make(MAKES[rng.next_less_than(MAKES.len() as u32) as usize].into());
86+
car.set_model(MODELS[rng.next_less_than(MODELS.len() as u32) as usize].into());
8787

8888
car.set_color(
8989
(rng.next_less_than(Color::Silver as u32 + 1) as u16)

benchmark/catrank.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl crate::TestCase for CatRank {
8484
snippet.push_str(WORDS[rng.next_less_than(WORDS.len() as u32) as usize]);
8585
}
8686

87-
result.set_snippet(&snippet);
87+
result.set_snippet(snippet[..].into());
8888
}
8989

9090
good_count
@@ -101,7 +101,7 @@ impl crate::TestCase for CatRank {
101101
for i in 0..results.len() {
102102
let result = results.get(i);
103103
let mut score = result.get_score();
104-
let snippet = result.get_snippet()?;
104+
let snippet = result.get_snippet()?.to_str()?;
105105
if snippet.contains(" cat ") {
106106
score *= 10000.0;
107107
}

capnp-futures/test/test.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,32 @@ mod tests {
3535
{
3636
let mut alice = people.reborrow().get(0);
3737
alice.set_id(123);
38-
alice.set_name("Alice");
39-
alice.set_email("alice@example.com");
38+
alice.set_name("Alice".into());
39+
alice.set_email("alice@example.com".into());
4040
{
4141
let mut alice_phones = alice.reborrow().init_phones(1);
42-
alice_phones.reborrow().get(0).set_number("555-1212");
42+
alice_phones.reborrow().get(0).set_number("555-1212".into());
4343
alice_phones
4444
.reborrow()
4545
.get(0)
4646
.set_type(person::phone_number::Type::Mobile);
4747
}
48-
alice.get_employment().set_school("MIT");
48+
alice.get_employment().set_school("MIT".into());
4949
}
5050

5151
{
5252
let mut bob = people.get(1);
5353
bob.set_id(456);
54-
bob.set_name("Bob");
55-
bob.set_email("bob@example.com");
54+
bob.set_name("Bob".into());
55+
bob.set_email("bob@example.com".into());
5656
{
5757
let mut bob_phones = bob.reborrow().init_phones(2);
58-
bob_phones.reborrow().get(0).set_number("555-4567");
58+
bob_phones.reborrow().get(0).set_number("555-4567".into());
5959
bob_phones
6060
.reborrow()
6161
.get(0)
6262
.set_type(person::phone_number::Type::Home);
63-
bob_phones.reborrow().get(1).set_number("555-7654");
63+
bob_phones.reborrow().get(1).set_number("555-7654".into());
6464
bob_phones
6565
.reborrow()
6666
.get(1)

capnp-rpc/examples/hello-world/client.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
5858
tokio::task::spawn_local(rpc_system);
5959

6060
let mut request = hello_world.say_hello_request();
61-
request.get().init_request().set_name(&msg);
61+
request.get().init_request().set_name(msg[..].into());
6262

6363
let reply = request.send().promise.await?;
6464

65-
println!("received: {}", reply.get()?.get_reply()?.get_message()?);
65+
println!(
66+
"received: {}",
67+
reply.get()?.get_reply()?.get_message()?.to_str()?
68+
);
6669
Ok(())
6770
})
6871
.await

capnp-rpc/examples/hello-world/server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ impl hello_world::Server for HelloWorldImpl {
3636
mut results: hello_world::SayHelloResults,
3737
) -> Promise<(), ::capnp::Error> {
3838
let request = pry!(pry!(params.get()).get_request());
39-
let name = pry!(request.get_name());
39+
let name = pry!(pry!(request.get_name()).to_str());
4040
let message = format!("Hello, {name}!");
4141

42-
results.get().init_reply().set_message(&message);
42+
results.get().init_reply().set_message(message[..].into());
4343

4444
Promise::ok(())
4545
}

capnp-rpc/examples/pubsub/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl subscriber::Server<::capnp::text::Owned> for SubscriberImpl {
3535
) -> Promise<(), ::capnp::Error> {
3636
println!(
3737
"message from publisher: {}",
38-
pry!(pry!(params.get()).get_message())
38+
pry!(pry!(pry!(params.get()).get_message()).to_str())
3939
);
4040
Promise::ok(())
4141
}

capnp-rpc/examples/pubsub/server.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,10 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
167167
subscriber.requests_in_flight += 1;
168168
let mut request = subscriber.client.push_message_request();
169169
request.get().set_message(
170-
&format!("system time is: {:?}", ::std::time::SystemTime::now())[..])?;
170+
(&format!("system time is: {:?}", ::std::time::SystemTime::now())
171+
[..])
172+
.into(),
173+
)?;
171174
let subscribers2 = subscribers1.clone();
172175
tokio::task::spawn_local(request.send().promise.map(
173176
move |r| match r {

capnp-rpc/src/rpc.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ fn to_pipeline_ops(
355355
}
356356

357357
fn from_error(error: &Error, mut builder: exception::Builder) {
358-
builder.set_reason(&error.to_string());
358+
builder.set_reason(error.to_string()[..].into());
359359
let typ = match error.kind {
360360
::capnp::ErrorKind::Failed => exception::Type::Failed,
361361
::capnp::ErrorKind::Overloaded => exception::Type::Overloaded,
@@ -379,10 +379,14 @@ fn remote_exception_to_error(exception: exception::Reader) -> Error {
379379
(Ok(exception::Type::Unimplemented), Ok(reason)) => {
380380
(::capnp::ErrorKind::Unimplemented, reason)
381381
}
382-
_ => (::capnp::ErrorKind::Failed, "(malformed error)"),
382+
_ => (::capnp::ErrorKind::Failed, "(malformed error)".into()),
383+
};
384+
let reason_str = match reason.to_str() {
385+
Ok(s) => s,
386+
Err(_) => "<malformed utf-8 in error reason>",
383387
};
384388
Error {
385-
extra: format!("remote exception: {reason}"),
389+
extra: format!("remote exception: {reason_str}"),
386390
kind,
387391
}
388392
}

capnp-rpc/test/impls.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ impl test_interface::Server for TestInterface {
148148
}
149149
{
150150
let mut results = results.get();
151-
results.set_x("foo");
151+
results.set_x("foo".into());
152152
}
153153
Promise::ok(())
154154
}
@@ -190,7 +190,7 @@ impl test_interface::Server for TestExtends {
190190
}
191191
{
192192
let mut results = results.get();
193-
results.set_x("bar");
193+
results.set_x("bar".into());
194194
}
195195
Promise::ok(())
196196
}
@@ -259,7 +259,7 @@ impl test_pipeline::Server for TestPipeline {
259259
return Err(Error::failed("expected x to equal 'foo'".to_string()));
260260
}
261261

262-
results.get().set_s("bar");
262+
results.get().set_s("bar".into());
263263

264264
// TODO implement better casting
265265
results
@@ -352,7 +352,7 @@ impl test_more_stuff::Server for TestMoreStuff {
352352
if response?.get()?.get_x()? != "foo" {
353353
return Err(Error::failed("expected x to equal 'foo'".to_string()));
354354
}
355-
results.get().set_s("bar");
355+
results.get().set_s("bar".into());
356356
Ok(())
357357
}))
358358
}
@@ -372,7 +372,7 @@ impl test_more_stuff::Server for TestMoreStuff {
372372
if response?.get()?.get_x()? != "foo" {
373373
return Err(Error::failed("expected x to equal 'foo'".to_string()));
374374
}
375-
results.get().set_s("bar");
375+
results.get().set_s("bar".into());
376376
Ok(())
377377
})
378378
}))
@@ -438,7 +438,7 @@ impl test_more_stuff::Server for TestMoreStuff {
438438
if response?.get()?.get_x()? != "foo" {
439439
Err(Error::failed("expected X to equal 'foo'".to_string()))
440440
} else {
441-
results.get().set_s("bar");
441+
results.get().set_s("bar".into());
442442
Ok(())
443443
}
444444
}))

capnp-rpc/test/reconnect_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl test_interface::Server for TestInterfaceImpl {
7676
);
7777
{
7878
let mut results = results.get();
79-
results.set_x(&s);
79+
results.set_x(s[..].into());
8080
}
8181
if let Some(fut) = self.inner.borrow().block.as_ref() {
8282
Promise::from_future(fut.clone())
@@ -91,7 +91,7 @@ where
9191
F: Future<Output = capnp::Result<Response<test_interface::foo_results::Owned>>>,
9292
{
9393
match pool.run_until(fut) {
94-
Ok(resp) => Ok(resp.get()?.get_x()?.to_string()),
94+
Ok(resp) => Ok(resp.get()?.get_x()?.to_string()?),
9595
Err(err) => Err(err),
9696
}
9797
}

0 commit comments

Comments
 (0)