Printing using fmt::Display - printing

I am trying to print an enum (or structure) using fmt::Display. Though the code compiles and gets to the display method, it doesn't print the value.
pub enum TestEnum<'a> {
Foo(&'a str),
Bar(f32)
}
impl<'b> fmt::Display for TestEnum <'b> {
fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
println!("Got this far");
match self{
&TestEnum::Foo(x) => write!(f,"{}",x),
&TestEnum::Bar(x) => write!(f,"{}",x),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_print() {
let cell = TestEnum::Str("foo");
println!("Printing");
println!("{}",cell); // No output here
}
}
I tried using {:?} and {} but to no avail.

This happens because Rust test program hides stdout of successful tests. You can disable this behavior passing --nocapture option to test binary or to cargo test command this way:
cargo test -- --nocapture
PS: your code is broken/incomplete

The test runner seems to divert the standard output; you should consider using assert!, assert_eq! or other panicky ways to test your assertions rather than printing in tests.
Besides, your code fails to compile due to mismatching names. I got it working as expected from main:
use std::fmt;
pub enum TestEnum<'a> {
Foo(&'a str),
Bar(f32)
}
impl<'b> fmt::Display for TestEnum <'b> {
fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
match self {
&TestEnum::Foo(x) => write!(f, "{}", x),
&TestEnum::Bar(x) => write!(f, "{}", x),
}
}
}
fn main() {
let cell = TestEnum::Foo("foo");
println!("Printing");
println!("{}", cell);
}

Test output is redirected to a buffer when the test succeeds as to not mangle up with the test "FAILED" or "ok" messages.
If you just want to test something while developing your test, you can always add a panic!() at the end of your test to make sure it keeps failing and outputting all logging. Or as #AndreaP notes in his answer, you can use cargo test -- --nocapture to display the standard output of all tests.
Usually a test should not write to stdout, but instead write to a buffer and check whether that buffer contains what it should:
let cell = TestEnum::Foo("foo");
let mut buf = Vec::new();
let _ = write!(buf, "{}\n", cell);
assert_eq!(&buf, b"foo\n");
If you truly want to output something, you need to write directly to stdout.
let _ = write!(io::stdout(), "{}\n", cell);
but this will mix with the test's output:
test tests::blub ... foo
ok
PlayPen

Related

How can I receive data by POST in Hyper?

What I want to do is really what the title says. I would like to know how I can receive data per post in hyper, for example, suppose I execute the following command (with a server in hyper running on port :8000):
curl -X POST -F "field=#/path/to/file.txt" -F "tool=curl" -F "other-file=#/path/to/other.jpg" http://localhost:8000
Now, I'm going to take parf of the code on the main page of hyper as an example:
use std::{convert::Infallible, net::SocketAddr};
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
async fn handle(_: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new("Hello, World!".into()))
}
#[tokio::main]
async fn main() {
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
let make_svc = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(handle))
});
let server = Server::bind(&addr).serve(make_svc);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
So, now, with this basic code, how can I receive the data per post that my curl command above would send? How do I adapt my code to read the data? I've tried to search the internet, but what I found was that hyper doesn't actually split the request body depending on the HTTP method, it's all part of the same body. But I haven't been able to find a way to process data like the above with code like mine. Thanks in advance.
Edit
I tried the exact code that they left me in the answer. That is, this code:
async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let mut files = multipart::server::Multipart::from(req);
.....
}
But I get this error:
expected struct multipart::server::Multipart, found struct
hyper::Request
How can I solve that?
It is a single body, but the data is encoded in a way that contains the multiple files.
This is called multipart, and in order to parse the body correctly you need a multipart library such as https://crates.io/crates/multipart
To hyper integration you need to add the feature flag hyper in Cargo.toml
multipart = { version = "*", features = ["hyper"] }
Then
async fn handle(mut files: multipart::server::Multipart) -> Result<Response<Body>, Infallible> {
files.foreach_entry(|field| {
// contains name, filename, type ..
println!("Info: {:?}",field.headers);
// contains data
let mut bytes:Vec<u8> = Vec::new();
field.data.read_to_end(&mut bytes);
});
Ok(Response::new("Received the files!".into()))
}
You can also use it like this
async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let mut files = multipart::server::Multipart::from(req);
.....
}

KMM ios flow.combine throwing no event loop error

suspend fun heyStackOverFlow(): Int {
val flow1 = flow<Int> { 1 }
val flow2 = flow<Int> { 2 }
return flow1.combine(flow2) { f1, f2 -> f1 + f2 }.single()
}
I use this in build.gradle
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
...
}
}
I get this error
kotlin.IllegalStateException: There is no event loop. Use runBlocking { ... } to start one.
I've tried playing around with actual / expected dispatchers from other questions but no success.
On android this works perfectly, on ios it doesn't.
You could check gradle dependencies as some 3rd party might be pulling in a non native-mt version of coroutines.
If that's the case you can force using the native-mt version as suggested by Philip:
version {
strictly("1.5.2-native-mt")
}

Why can't we make a good comparison? ruby-ffi call golang(so files)

I'm calling shared files created by Golang from ruby-ffi.
However, when I run Golang alone, the process works, but when I run it via ruby-ffi, the comparison doesn't work.
package main
import (
"C"
"fmt"
)
//export zen_roma_to_han_roma
func zen_roma_to_han_roma(s string) string {
if s=="test" {
return "10"
}
return s
}
func main(){
fmt.Println(zen_roma_to_han_roma("test"))
}
$ go run replace.go
10
Here's an example of what can go wrong.
First, create a go build and load it.
go build -buildmode=c-shared -o replace.so replace.go
module Sample
extend FFI::Library
ffi_lib 'replace.so'
attach_function :zen_roma_to_han_roma, [:string], :string
end
[5] pry(main)> Sample.zen_roma_to_han_roma("test")
=> "test
I don't know the cause of this and I need your help.
Is there anything else I should try?
I am not a Golang programmer but still here is a quote from the FFI gem documentation
:string should be considered to be const char * and the Ruby string must not be changed as long as it’s accessed by the library. If the string buffer shall be modified from C or Ruby side, use :pointer and FFI::MemoryPointer instead.
So you should pass *C.char as an argument and return a value of the same type instead of string.
package main
import (
"C"
"fmt"
)
//export zen_roma_to_han_roma
func zen_roma_to_han_roma(s *C.char) *C.char {
test_string := C.GoString(s)
if test_string == "test" {
return C.CString("10")
}
return s
}
func main() {
fmt.Println(C.GoString(zen_roma_to_han_roma(C.CString("test"))))
}

Capturing the same variable in one of multiple closures

I have two closures that capture the same Vec and I don't know how to write this in idiomatic Rust:
use std::error;
fn get_token -> Box<Vec<u8>>() {...}
fn do_stuff(file: &str) -> std::io::Result<i32> {...}
fn do_other_stuff(a: &str, a: &str) -> std::io::Result<i32> {...}
enum MyError {
IoError { token: Vec<u8>, reason: String ),
}
fn consumer() -> Result<MyError, ()> {
let token = get_token();
try!(do_stuff("a")
.map_err(|e| MyError::IoError { token: token, reason: "foo".to_str() }));
try!(do_other_stuff("b", "c")
.map_err(|e| MyError::IoError { token: token, reason: "bar".to_str() }));
}
I could replace the map_err calls with match expressions but I really am stumped by this: how do I pass a Vec to multiple closures?
First of all: Please make sure to provide an MCVE in the future, it's not fun to have to fix syntax errors before being able to reproduce your problem: http://is.gd/tXr7WK
Rust does not know that the only way the second closure can run, is if the first closure did not run and will never run. You can either wait for the let/else RFC to be accepted, implemented and stabilized, or you can create your error in steps, first create an inner closure that does all the operations for that one error kind without using up the token, then run the closure, then map the error to your custom error type.
|| -> _ {
try!(do_stuff("a").map_err(|e| ("foo".to_owned(), e)));
try!(do_other_stuff("b","c").map_err(|e| ("bar".to_owned(), e)));
Ok(())
} ().map_err(|(reason, e)| MyError::IoError{ token: token, reason: reason })
There's something weird going on where the closure requires us to specify that it returns something with -> _, but I'm not sure what it is.
Much more straightforward is to just not use try! or closures:
if let Err(e) = do_stuff("a") {
return Err(MyError::IoError{token: token, reason: "foo".to_owned()});
}
if let Err(e) = do_other_stuff("b", "c") {
return Err(MyError::IoError{token: token, reason: "bar".to_owned()});
}
This lets Rust perform straightforward analysis like you want it to, and is much more readable than dancing through hoops.
You can use and_then() combinator to avoid additional closure:
try!(do_stuff("a").map_err(|_| "foo" )
.and_then(|_|
do_other_stuff("b","c").map_err(|_| "bar")
)
.map_err(|e| MyError::IoError{token:token,reason:e.into()})
);

Can I load custom jsm modules in bootstrap.js of a restartless add-on?

I'm trying to load a custom module in a restartless add-on, using the following:
chrome/content/modules/Test.jsm:
var EXPORTED_SYMBOLS = [ 'Test' ];
let Test = {};
chrome.manifest:
content test chrome/content/
bootstrap.js:
const Cu = Components.utils;
// Tried this first, but figured perhaps chrome directives aren't loaded here yet
// let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
function install() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function uninstall() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function startup() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
function shutdown() {
let test = Cu.import( 'chrome://test/modules/Test.jsm', {} ).Test;
}
However, I get the following types of WARN messages (this one was for shutdown(), but basically identical for all functions and in the earlier attempt in the global scope):
1409229174591 addons.xpi WARN Exception running bootstrap method
shutdown on test#extensions.codifier.nl: [Exception... "Component
returned failure code: 0x80070057 (NS_ERROR_ILLEGAL_VALUE)
[nsIXPCComponents_Utils.import]" nsresult: "0x80070057
(NS_ERROR_ILLEGAL_VALUE)" location: "JS frame ::
resource://gre/modules/addons/XPIProvider.jsm ->
file:///test/bootstrap.js :: shutdown :: line 21" data: no] Stack
trace: shutdown()#resource://gre/modules/addons/XPIProvider.jsm ->
file:///test/bootstrap.js:21 <
XPI_callBootstrapMethod()#resource://gre/modules/addons/XPIProvider.jsm:4232
<
XPI_updateAddonDisabledState()#resource://gre/modules/addons/XPIProvider.jsm:4347
<
AddonWrapper_userDisabledSetter()#resource://gre/modules/addons/XPIProvider.jsm:6647
< uninstall()#extensions.xml:1541 < oncommand()#about:addons:1 <
Are chrome.manifest directives not yet available in bootstrap.js? Or is what I am attempting some kind of security violation, perhaps? Or am I simply doing something trivially wrong?
What I was hoping to achieve, is that I could do something like the following:
chrome/content/modules/Test.jsm:
var EXPORTED_SYMBOLS = [ 'Test' ];
let Test = {
install: function( data, reason ) {
},
/* etc */
bootstrap: function( context ) {
context.install = this.install;
context.uninstall = this.uninstall;
context.startup = this.startup;
context.shutdown = this.shutdown;
}
}
bootstrap.js:
const Cu = Components.utils;
Cu.import( 'chrome://test/modules/Test.jsm' );
Test.bootstrap( this );
Perhaps it's a bit over the top to begin with, but I just kind of like the idea of hiding implementations in modules and/or objects and keeping bootstrap.js super clean.
If you happen to have suggestions on how to achieve this by other means: I'm all ears.
Yes you can your path is wrong though.
Just do this:
let test = Cu.import( 'chrome://test/content/modules/Test.jsm', {} ).Test;
notice the /content/
You don't have to do the .Test unless you want the lower case test to hold it. You can just do:
Cu.import( 'chrome://test/content/modules/Test.jsm');
and use as Test.blah where blah is whatever is in the JSM module.
This code can go anywhere, it does not have to be in the install function.
Make sure to unload the custom JSM modules or else it can lead to zombie compartments which is bad for memory. Read here:
last paragraph here: https://developer.mozilla.org/en-US/docs/Extensions/Common_causes_of_memory_leaks_in_extensions
more reading but optional: https://developer.mozilla.org/en-US/docs/Zombie_compartments
Beyond #Noitidart's answer, you don't have to use chrome.manifest' and register a content package if your only concern is how to import your module.
function install(data, reason) {
Components.utils.import(data.resourceURI.spec + "relative/path/to/your/module.jsm");
}

Resources