Yes; wait for Erick to submit the PR that fixes extra::json to use &mut
Writer rather than @mut Writer, so that one can write something like
pub fn buffer_encode<T:Encodable<Encoder>>(to_encode_object: &T) ->
~[u8] {
let mut m = MemWriter::new();
{ // I think this scope is necessary to restrict the borrows
let mut encoder = Encoder(&mut m as &mut Writer);
to_encode_object.encode(&mut encoder);
}
m.inner()
}
One is then just moving the `~[u8]` around without copying all the elements.
Also, `str_encode` shouldn't need to do any additional copies, even
right now, since the `std::str::from_utf8_owned` function exists.
(`from_utf8` is bad with its implicit and normally unnecessary copy,
I've got https://github.com/mozilla/rust/pull/10701 open that removes
that function for that reason.)
(Tangentially (and a genuine question), do we really need these
functions in extra::json (assuming this is part of the plan)? How often
does one need to encode to a buffer or string, rather than to stdout, a
file or network socket, which can be done by writing directly to the
corresponding writers.)
Huon
On 29/11/13 23:57, Philippe Delrieu wrote:
I try to implement the two methods and I have a problem with the copy
of memory.
The first attempt :
pub fn buffer_encode<T:Encodable<Encoder>>(to_encode_object: &T) ->
~[u8] {
//Serialize the object in a string using a writer
let m = @mut MemWriter::new();
let mut encoder = Encoder(m as @mut Writer);
to_encode_object.encode(&mut encoder);
let buff:&~[u8] = m.inner_ref();
(buff.clone())
}
pub fn str_encode<T:Encodable<Encoder>>(to_encode_object: &T) -> ~str {
let buff:~[u8] = buffer_encode(to_encode_object);
str::from_utf8(*buff)
}
When I call str_encode I copy at least two times the content of the
MemWriter buffer (one inside clone and one inside from_utf8).
If I implements str_encode like that
pub fn str_encode<T:Encodable<Encoder>>(to_encode_object: &T) -> ~str {
let m = @mut MemWriter::new();
let mut encoder = Encoder(m as @mut Writer);
to_encode_object.encode(&mut encoder);
let buff:&~[u8] = m.inner_ref();
str::from_utf8(*buff)
}
I'll do at least one copy (one less than the other impl) but the code
is copied.
Is there a better way to manage pointer of memory across function calls?
Philippe
Le 29/11/2013 12:55, Philippe Delrieu a écrit :
I made a remark about that on the GitHub pull request where the idea
was proposed. I'm agree with you. It's simplier to return a str or
perhaps a [u8] if it's use in a stream purpose.
I'm not very fan of creating a MemWriter and return it.
I'll modify to add two functions:
pub fn str_encode<T:Encodable<Encoder>>(to_encode_object: &T) -> ~str
pub fn buffer_encode<T:Encodable<Encoder>>(to_encode_object: &T) -> ~[u8]
and remove the other.
Any remaqs?
Philippe
Le 29/11/2013 10:44, Gaetan a écrit :
I would prefere this function returns a str.
Le 29 nov. 2013 09:27, "Philippe Delrieu" <[email protected]
<mailto:[email protected]>> a écrit :
Thank you for the help. I've try this signature and I had an
compile error. I thought it came from the signature but the
problem when from the call.
It works now.
For the return type @mut MemWriter I work on the json doc and
some example of use. I can make the change. I didn't find the
issue about it. Did you create it?
Philippe
Le 28/11/2013 22:27, Erick Tryzelaar a écrit :
Good afternoon Phillippe,
Here's how to do it, assuming you're using rust 0.8 and the
json library:
```
#[feature(managed_boxes)];
extern mod extra;
use std::io::mem::MemWriter;
use extra::serialize::{Encoder, Encodable};
use extra::json;
pub fn memory_encode<
T: Encodable<json::Encoder>
>(to_encode_object: &T) -> @mut MemWriter {
//Serialize the object in a string using a writer
let m = @mut MemWriter::new();
let mut encoder = json::Encoder(m as @mut Writer);
to_encode_object.encode(&mut encoder);
m
}
fn main() {
}
```
Regarding the trouble returning a `MemWriter` instead of a
`@mut MemWriter`, the easiest thing would be to fix library to
use `&mut ...` instead of `@mut ...`. I'll put in a PR to do that.
On Thu, Nov 28, 2013 at 3:55 AM, Philippe Delrieu
<[email protected] <mailto:[email protected]>> wrote:
I try to develop a function that take a Encodable parameter
but I have the error wrong number of type arguments:
expected 1 but found 0
pub fn memory_encode(to_encode_object:
&serialize::Encodable) -> @mut MemWriter {
//Serialize the object in a string using a writer
let m = @mut MemWriter::new();
let mut encoder = Encoder(m as @mut Writer);
to_encode_object.encode(&mut encoder);
m
}
The encodable trait is :
pub trait Encodable<S:Encoder> {
fn encode(&self, s: &mut S);
}
I try this definition
memory_encode<T:serialize::Encodable<Encoder>>(to_encode_object:
&T) -> @mut MemWriter
But I can't use the method with a struct that implement
Encodable. The error : mismatched types: expected `&<V31>`
but found ..
I have another question :
I would like to return a MemWriter and not a @mut MemWriter
. I didn't find a way to convert the @mut to ~
Philippe Delrieu
_______________________________________________
Rust-dev mailing list
[email protected] <mailto:[email protected]>
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected] <mailto:[email protected]>
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev