The function is executed without error and returns Ok(()), but the text is not pushed into the clipboard:
pub fn copy_text(text_fragment: winrt::HString) -> winrt::Result<()> {
let data_package = DataPackage::new()?;
data_package.set_text(text_fragment)?;
Clipboard::set_content(data_package)
}
The documentation about the Windows runtime API has the following statement for the Clipboard.SetContent(DataPackage) function:
Use this method after creating and defining a DataPackage with the data you want to put on the clipboard. Call this method only when the application is in the foreground, or when a debugger is attached.
Is there any way I can use that function without a UI?
I don't know whether it's officially supported on a non-UI thread, but it seems to work if you add a call to flush as follows:
use windows::application_model::data_transfer::*;
fn main() -> winrt::Result<()> {
let content = DataPackage::new()?;
content.set_text("hello world from Rust")?;
Clipboard::set_content(content)?;
Clipboard::flush()?;
Ok(())
}
The flush method ensures that the content is copied onto the clipboard and will remain there even if the sending application/process terminates.
Related
I am new in rusting studying. when i am trying to execute some codes written by Rust in jupyter-notebook. I can not get any print out. but it can be executed via vscode or terminal.
no print out in jupyter-notebook
Here is my code:
// Derive the `fmt::Debug` implementation for `Structure`. `Structure`
// is a structure which contains a single `i32`.
#[derive(Debug)]
struct Structure(i32);
// Put a `Structure` inside of the structure `Deep`. Make it printable
// also.
#[derive(Debug)]
struct Deep(Structure);
fn main() {
// Printing with `{:?}` is similar to with `{}`.
println!("{:?} months in a year.", 12);
println!("{1:?} {0:?} is the {actor:?} name.",
"Slater",
"Christian",
actor="actor's");
// `Structure` is printable!
println!("Now {:?} will print!", Structure(3));
// The problem with `derive` is there is no control over how
// the results look. What if I want this to just show a `7`?
println!("Now {:?} will print!", Deep(Structure(7)));
}
snapshot for successful running in vscode
successful print out
So, What's wrong? Are there any bugs for evcxr?
The issue here is the usage of fn main. See https://github.com/google/evcxr/issues/183.
In a EVCXR notebook, main is not a special function. Thus, writing the following simply creates a function called main:
fn main() {
println!("Hello, world!");
}
To have the code within main actually run, one would need to call main explicitly:
main()
// => Hello, world!
Generally, in a jupyter notebook a main function is not even used at all. This is of course different from a normal rust executable which requires a main function.
Credits to finding the issue's root cause goes to #Jun Lv. I have simply added some reasoning as to why the fix works/problem occurs.
mod loginfo{
use std::io::Error;
use chrono::prelude::*;
use std::io::prelude::*;
use std::fs::OpenOptions;
const LOG_SYS :&'static str = "log.txt";
const LOG_ERR :&'static str = "log_error.txt";
pub fn set_log_error(info: String)->Result<(), String>{
let mut handler = OpenOptions::new().append(true)
.open(LOG_ERR);
if handler.is_err(){
create_file(LOG_ERR.to_owned()).unwrap();
set_log_error(info).unwrap();
}
if let Err(_errno) = handler.write_fmt(
format_args!("{:?}\t{:?} ->[Last OS error({:?})]\n",
Utc::now().to_rfc2822().to_string(), info,
Error::last_os_error()) ){
panic!(
"\nCannot write info log error\t Info\t:{:?}\n",
Error::last_os_error());
}
Ok(())
}
pub fn set_log(info: String)->Result<(), String>{
let mut handler = OpenOptions::new().append(true)
.open(LOG_SYS);
if handler.is_err(){
set_log_error("Cannot write info log".to_owned())
.unwrap();
}
if let Err(_errno) = handler.write_fmt(
format_args!("{:?}\t{:?}\n",
Utc::now().to_rfc2822().to_string(), info)){
set_log_error("Cannot write data log file".to_owned())
.unwrap();
}
Ok(())
}
pub fn create_file(filename : String)->Result<(), String>{
let handler = OpenOptions::new().write(true)
.create(true).open(filename);
if handler.is_err(){
panic!(
"\nCannot create log file\t Info\t:{:?}\n",
Error::last_os_error());
}
Ok(())
}
}
When compiling, I get the following errors, "error[E0599]: no method named write_fmt found for enum std::result::Result<std::fs::File, std::io::Error> in the current scope --> src/loginfo.rs:19:38`"
but despite using the right imports, I still get the same errors. Is this due to a bad implementation of the module?
Thank you in advance for your answers and remarks?
+1 #Masklinn Ok I think I understand it would be easier to just write
pub fn foo_write_log( info: String){
let mut handler = OpenOptions::new().append(true)
.create(true).open(LOG_SYS).expect("Cannot create log");
handler.write_fmt(
format_args!("{:?}\t{:?} ->[Last OS error({:?})]\n",
Utc::now().to_rfc2822().to_string(), info,
Error::last_os_error())).unwrap();
}
but despite using the right imports, I still get the same errors. Is this due to a bad implementation of the module?
Kind-of? If you look at the type specified in the error, handler is a Result<File, Error>. And while io::Write is implemented on File, it's not implemented on Result.
The problem is that while you're checking whether handler.is_err() you never get the file out of it, nor do you ever return in the error case. Normally you'd use something like match or if let or one of the higher-order methods (e.g. Result::map, Result::and_then) in order to handle or propagate the various cases.
And to be honest the entire thing is rather odd and awkward e.g. your functions can fail but they panic instead (you never actually return an Err); if you're going to try and create a file when opening it for writing fails, why not just do that directly[0]; you are manually calling write_fmt and format_args why not just write!; write_fmt already returns an io::Error why do you discard it then ask for it again via Error::last_os_error; etc...
It's also a bit strange to hand-roll your own logger thing when the rust ecosystem already has a bunch of them though you do you; and the naming is also somewhat awkward e.g. I'd expect something called set_X to actually set the X, so to me set_log would be a way to set the file being logged to.
[0] .create(true).append(true) should open the file in append mode if it exists and create it otherwise; not to mention your version has a concurrency issue: if the open-for-append fails you create the file in write mode, but someone else could have created the file -- with content -- between the two calls, in which case you're going to partially overwrite the file
I want to use the crate dialoguer to let the user check and correct some suggested data.
Cargo.toml dependencies
[dependencies]
dialoguer = "0.7"
src/main.rs
use dialoguer::Input;
fn main() {
// searching the web
std::thread::sleep(std::time::Duration::from_secs(5));
let suggestion = "Catpictures".to_string();
let data : String = Input::new()
.with_prompt("suggested")
.with_initial_text(suggestion)
.interact_text()
.expect("failed to correct suggestion");
}
My problem is that, while the program searches for the suggestion, the user might start typing and may press ENTER.
Then the program displays the suggestion and immediately accepts the answer.
I would like to prevent this behavior.
Current behavior:
starting program
hitting enter (for what ever reason)
program displays suggestion and immediately accepts suggestion
desired behavior:
starting program
hitting enter (for what ever reason)
program displays suggestion
user can edit suggestion and accept with enter
Is there a way to clear the input?
Neither the standard library nor dialoguer features functionality for clearing stdin.
One workaround is to use the AsyncReader from the crossterm_input crate, in which you can poll input (events) from the stdin. That way you'll be able to clear any pending input, before using dialoguer.
// crossterm_input = "0.5"
fn clear_stdin() {
let input = crossterm_input::input();
let mut async_stdin = input.read_async();
while let Some(_) = async_stdin.next() {}
}
Your updated example, will then look like this:
use dialoguer::Input;
fn main() {
// searching the web
thread::sleep(time::Duration::from_millis(200));
let suggestion = "Catpictures".to_string();
clear_stdin();
let data = Input::new()
.with_prompt("suggested")
.with_initial_text(suggestion)
.interact_text()
.expect("failed to correct suggestion");
}
I got really stuck at this very simple problem in rust:
Ideally using a single core CPU, I want to be able to read a parts of the same file in a non blocking way:
struct PrefetchOp {
}
impl PrefetchOp {
async fn start (currentData: [u8;8]) {
let next = self.prefetch(); // this reads data from disk and puts it in memory
self.perform_slow_step(currentData);
let mut future
for x in 0..100 {
future = self.prefetch();
self.perform_slow_step(next.await);
next = future;
}
}
}
Now, I want to write a prefetch which reads data in an async way such that hopefully it will be ready by the next slow step or that line will wait for it to be done.
Now, prefetch is reading parts of the same file and my plan was to:
Implement a future that creates the file descriptor, performs a poll_seek and performs poll_read
Or, create a file descriptor before the loop and have a future that does the poll_seek and the poll_read. Will I not have concurrency issues then?
How can I do this in the simplest most elegant way?
I'm trying to write a simple game that runs in the browser, and I'm having a hard time modeling a game loop given the combination of restrictions imposed by the browser, rust, and wasm-bindgen.
A typical game loop in the browser follows this general pattern:
function mainLoop() {
update();
draw();
requestAnimationFrame(mainLoop);
}
If I were to model this exact pattern in rust/wasm-bindgen, it would look like this:
let main_loop = Closure::wrap(Box::new(move || {
update();
draw();
window.request_animation_frame(main_loop.as_ref().unchecked_ref()); // Not legal
}) as Box<FnMut()>);
Unlike javascript, I'm unable to reference main_loop from within itself, so this doesn't work.
An alternative approach that someone suggested is to follow the pattern illustrated in the game of life example. At a high-level, it involves exporting a type that contains the game state and includes public tick() and render() functions that can be called from within a javascript game loop. This doesn't work for me because my gamestate requires lifetime parameters, since it effectively just wraps a specs World and Dispatcher struct, the latter of which has lifetime parameters. Ultimately, this means that I can't export it using #[wasm_bindgen].
I'm having a hard time finding ways to work around these restrictions, and am looking for suggestions.
The easiest way to model this is likely to leave invocations of requestAnimationFrame to JS and instead just implement the update/draw logic in Rust.
In Rust, however, what you can also do is to exploit the fact that a closure which doesn't actually capture any variables is zero-size, meaning that Closure<T> of that closure won't allocate memory and you can safely forget it. For example something like this should work:
#[wasm_bindgen]
pub fn main_loop() {
update();
draw();
let window = ...;
let closure = Closure::wrap(Box::new(|| main_loop()) as Box<Fn()>);
window.request_animation_frame(closure.as_ref().unchecked_ref());
closure.forget(); // not actually leaking memory
}
If your state has lifetimes inside of it, that is unfortunately incompatible with returning back to JS because when you return all the way back to the JS event loop then all WebAssembly stack frames have been popped, meaning that any lifetime is invalidated. This means that your game state persisted across iterations of the main_loop will need to be 'static
I'm a Rust novice, but here's how I addressed the same issue.
You can eliminate the problematic window.request_animation_frame recursion and implement an FPS cap at the same time by invoking window.request_animation_frame from a window.set_interval callback which checks a Rc<RefCell<bool>> or something to see if there's an animation frame request still pending. I'm not sure if the inactive tab behavior will be any different in practice.
I put the bool into my application state since I'm using an Rc<RefCell<...>> to that anyway for other event handling. I haven't checked that this below compiles as is, but here's the relevant parts of how I'm doing this:
pub struct MyGame {
...
should_request_render: bool, // Don't request another render until the previous runs, init to false since we'll fire the first one immediately.
}
...
let window = web_sys::window().expect("should have a window in this context");
let application_reference = Rc::new(RefCell::new(MyGame::new()));
let request_animation_frame = { // request_animation_frame is not forgotten! Its ownership is moved into the timer callback.
let application_reference = application_reference.clone();
let request_animation_frame_callback = Closure::wrap(Box::new(move || {
let mut application = application_reference.borrow_mut();
application.should_request_render = true;
application.handle_animation_frame(); // handle_animation_frame being your main loop.
}) as Box<FnMut()>);
let window = window.clone();
move || {
window
.request_animation_frame(
request_animation_frame_callback.as_ref().unchecked_ref(),
)
.unwrap();
}
};
request_animation_frame(); // fire the first request immediately
let timer_closure = Closure::wrap(
Box::new(move || { // move both request_animation_frame and application_reference here.
let mut application = application_reference.borrow_mut();
if application.should_request_render {
application.should_request_render = false;
request_animation_frame();
}
}) as Box<FnMut()>
);
window.set_interval_with_callback_and_timeout_and_arguments_0(
timer_closure.as_ref().unchecked_ref(),
25, // minimum ms per frame
)?;
timer_closure.forget(); // this leaks it, you could store it somewhere or whatever, depends if it's guaranteed to live as long as the page
You can store the result of set_interval and the timer_closure in Options in your game state so that your game can clean itself up if needed for some reason (maybe? I haven't tried this, and it would seem to cause a free of self?). The circular reference won't erase itself unless broken (you're then storing Rcs to the application inside the application effectively). It should also enable you to change the max fps while running, by stopping the interval and creating another using the same closure.