Tauri app crashes when running a command that writes to a file - rust

I created a tauri command that creates a file and writes data to it, however, every time I invoke the command from the frontend, the app crashes and restarts.
the command looks something like this
#[tauri::command]
pub fn create_file(name: String, data: String) {
if let Ok(mut out) = File::create(format!("./src/ext/{}", name)) {
out.write(data.as_bytes());
}
}
Is there a way to fix this issue?

Related

Why did error not trigger when println was run?

I was trying to trace the error in my Rust API code. When I ran it, it showed the following in the terminal:
Server running on localhost:3000
auth
auth err1
...
Notice auth err1 was printed from inside .ok_or() in my code below, but the StatusCode::BAD_REQUEST was not triggered as I got 200 OK back. Why? What happened?
pub async fn auth<T>(mut request: Request<T>, next: Next<T>) -> Result<Response, StatusCode> {
println!("auth");
let token = request
.headers()
.typed_get::<Authorization<Bearer>>()
.ok_or({
println!("auth err1");
StatusCode::BAD_REQUEST
})?
.token()
.to_owned();
//other code to connect to DB and retrieve user data...
}
Since you put println!("auth err1") in a block it will immediately be executed no matter if typed_get returned Some or None.
You need to make it a closure and use ok_or_else to only print in the None case:
.ok_or_else(|| {
println!("auth err1");
StatusCode::BAD_REQUEST
})?

why there is no printout when using #[derive(Debug)] for rust in jupyter notebook?

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.

Some errors E0425 & E0599 write_fmt

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

Can I use the Clipboard.SetContent function in a CLI app?

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.

Converting a future to a stream in kube-rs library

I'm trying to implement a project where I can tail the logs of multiple Kubernetes container logs simultaneously. Think tmux split pane with two tails in each pane. Anyway, I'm far far away from my actual project because I'm stuck right at the beginning. If you look at the following code then the commented out line for lp.follow = true will keep the log stream open and stream logs forever. I'm not sure how to actually use this. I found a function called .into_stream() that I can tack onto the pods.log function, but then I'm not sure how to actually use the stream. I'm not experienced enough to know if this is a limitation of the kube library, or if I'm just doing something wrong. Anyway, here is the repo if you want to look at anything else. https://github.com/bloveless/kube-logger
I'd be forever grateful for any advice or resources I can look at. Thanks!
use kube::{
api::Api,
client::APIClient,
config,
};
use kube::api::{LogParams, RawApi};
use futures::{FutureExt, Stream, future::IntoStream, StreamExt};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
std::env::set_var("RUST_LOG", "info,kube=trace");
let config = config::load_kube_config().await?;
let client = APIClient::new(config);
// Manage pods
let pods = Api::v1Pod(client).within("fritzandandre");
let mut lp = LogParams::default();
lp.container = Some("php".to_string());
// lp.follow = true;
lp.tail_lines = Some(100);
let log_string = pods.log("fritzandandre-php-0", &lp).await?;
println!("FnA Log: {}", log_string);
Ok(())
}
Originally posted here https://www.reddit.com/r/learnrust/comments/eg49tx/help_with_futuresstreams_and_the_kubers_library/

Resources