Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    RuRu92
    @RuRu92
    Changing signature to something that expects a mutable reference as return?
    RuRu92
    @RuRu92

    Hmm.. now I managed to get this error

    = note: LINK : fatal error LNK1104: cannot open file

    RuRu92
    @RuRu92

    Got it working.. Would like some verification on if its done in correct way

     pub fn in_transaction<'a, R>(&self, db_access_mode: AccessMode, action: fn(con: &mut Transaction) -> Result<R>) -> R {
            let pool = self.pool.clone();
            let mut db_conn = pool.get_conn().expect("Unable to establish connection");
    
            let mut tx: Transaction = db_conn.start_transaction(TxOpts::default()
                .set_access_mode(Some(db_access_mode)))
                .expect("Failed to initialise transaction");
    
               return match action(&mut tx) {
                   Ok(res) => {
                       tx.commit().expect("Failed to commit");;
                       return res;
                   }
                   Err(x) => {
                       if db_access_mode != AccessMode::ReadOnly {
                           tx.rollback().expect("Failed to rollback");
                       }
                       panic!(x);
                   }
               };
            }

    and the caller

            let db = &data.db;
    
            let fetch_users_query = |tx: &mut Transaction|
                tx.query_map(
                    "SELECT id, role, name from user",
                    |(id, role, name)| {
                        Principal { id, role, name }
                    },
                );
    
            let users = db.in_transaction(AccessMode::ReadOnly,  fetch_users_query);
    Let me know what could be done better
    tanriol
    @tanriol:matrix.org
    [m]
    Looks good to me.
    RuRu92
    @RuRu92
    Nice, thanks @tanriol:matrix.org !
    MCF
    @mcf-rocks
    How to take action on not match
    pub enum Animal {
        Dog(u64),
        Cat,
    }
    
    fn main() {
        let a = Animal::Dog(3);
        if let Animal::Dog(n) = a {
            println!("dog {}",n);
        }
    }
    if it's anything other than Animal::Dog -- do something
    tanriol
    @tanriol:matrix.org
    [m]
    By adding an else ;-)
    MCF
    @mcf-rocks
    @tanriol:matrix.org without an empty if clause
    like in C
    if ( !something ) {
      printf("hello\n");
    }
    tanriol
    @tanriol:matrix.org
    [m]
    @mcf-rocks: Either an empty if, or a match with an empty branch for that case.
    Sorry, there's also if ! matches!(a, Animal::Dog(_)) { ... }
    MCF
    @mcf-rocks
    @tanriol:matrix.org so the only way to do it, without a tacky empty branch, is to place the word match between two exclamation marks - meaning totally different things... it's like god fell asleep and rust happened.
    thx for your help tho, is appreciated
    tanriol
    @tanriol:matrix.org
    [m]
    Well, you can also write or derive functions that would allow you to if !a.is_dog() { ... }, but there are none by default.
    RuRu92
    @RuRu92

    trying to understand closures/function pointers

    So in java it would be simple to have do this

    (db) -> { doSomething(someData, db); db.doMore(other, db) };

    now in rust I have trouble with scoping other variables

     return |tx: &mut Transaction| {
                let user_storage = UserStorage {};
                user_storage.create_from(user_data, tx)
            };

    Does user_data needs to be passed as a param to closure? Can it be done otherwise? Not having to pass it as param ?
    I am getting this error

       | |_________^ expected fn pointer, found closure
       |
       = note: expected fn pointer `for<'r, 's> fn(&'r mut Transaction<'s>) -> std::result::Result<std::string::String, mysql::Error>`
                     found closure `[closure@src\service\mod.rs:42:16: 46:10]`
    tanriol
    @tanriol:matrix.org
    [m]
    @RuRu92: There's a difference between function pointers (fn(args) -> output, cannot capture variables) and closures (impl Fn / FnMut / FnOnce(args) -> output, can capture variables). A closure that does not capture anything can be converted to a function pointer, and that's probably why you haven't noticed this problem before.
    RuRu92
    @RuRu92
    Ah, so I was working with function pointer, as my closure was not capturing anything
    So how should i change my signature and implement closure to be Fn/FnMut ?
    tanriol
    @tanriol:matrix.org
    [m]
    What's your signature?
    Ah, I see it above. I think that changing action to action: impl FnOnce(con: &mut Transaction) -> Result<R> should work if you don't need object safety.
    @RuRu92: By the way, an off-topic question: do I understand correctly that Java closures do not support checked exceptions like SQLException? Learning some Java now, and after Rust it feels... strange.
    RuRu92
    @RuRu92

    @tanriol:matrix.org
    Thanks, I will try that out! Why would it not give me object safety? Curious to understand how to make good rust code.

    As for the Java.
    If its in the lambda, you have to explicitly handle checked exceptions using try-catch, and convert that to a runtime exception.
    It may seem strange, but its other way around for me. Done Java for so many years, other languages seem so foreign :D
    But I am enjoying Rust, want to master it!

    RuRu92
    @RuRu92

    @tanriol:matrix.org
    To make it looks nicer when handling exception throwing code, you can implement a throwing functional interface.

    something like

    @FunctionalInterface
    public interface ThrowingConsumer<T, E extends Exception> {
        void accept(T t) throws E;
    }

    And then you when you call that, it will look better

    tanriol
    @tanriol:matrix.org
    [m]
    Object safety does not allow type (or const) generics because Rust does not do automatic type erasure. There are ways around that, usually by splitting the trait into two - the object-safe "core" and the "extras" for better ergonomics.
    RuRu92
    @RuRu92
    So for my case. the unsafe part is that I have generic in the Result<R> ?
    How would handle this?
    tanriol
    @tanriol:matrix.org
    [m]
    First, if you don't need in_transaction to be a part of an object-safe trait, you don't need to do anything :-)
    RuRu92
    @RuRu92

    So you saying that this is fine way to do it?
    I assume this code isnt going to be problematic due to object unsafety?

    Want to have this as production viable code :)

    tanriol
    @tanriol:matrix.org
    [m]
    This is a fine way - it has some limitations, but these may not matter for your use case.
    RuRu92
    @RuRu92
    Perfect! I can then continue on expanding the code.
    Once I got something full fledged, you could take a look at the repo?
    I like feedback :D
    tanriol
    @tanriol:matrix.org
    [m]
    If I have enough time.
    MCF
    @mcf-rocks
    how to use generic constants?
    fn from_str<const N: usize>(s: &str, N: usize) -> Box<[u8; N]> {
        return Box::new([1;N]);
    }
    how?
    tanriol
    @tanriol:matrix.org
    [m]
    You don't need N: usize in function arguments.
    MCF
    @mcf-rocks
    amazing
    Félix Lescaudey de Maneville
    @ManevilleF

    Hello, question on the cargo manifest:

    Can I disable a feature when one is enabled? My lib can be asynchronous or blocking but not both at the same time.

    Is there any way to disable the async feature when blocking is enabled?

    default = ["async"]
    blocking = ["blocking", !"async"]
    tanriol
    @tanriol:matrix.org
    [m]
    Sorry, no way. Furthermore, if this is a library, note that your user can have multiple crates that depend on it, some with blocking, some with async
    So designing a library in such a way that can be either but not both is usually not a good idea.
    Félix Lescaudey de Maneville
    @ManevilleF
    thank you
    Standaa
    @Standaa
    Hi all ! Looking for advice regarding a piece of code I wrote. Is there a way to improve this or make it more Rusty 🙂 ?
             let mut module_path = if ts_config_exist {
                format!("{}/migrations/deploy.ts", cur_dir.display())
            } else {
                format!("{}/migrations/deploy.js", cur_dir.display())
            };
    
            if ts_config_exist {
                if let Err(_e) = std::process::Command::new("tsc")
                    .arg(&module_path)
                    .stdout(Stdio::inherit())
                    .stderr(Stdio::inherit())
                    .output()
                {
                    std::process::exit(1);
                }
                module_path = format!("{}/migrations/deploy.js", cur_dir.display())
            }
    Itanq
    @Itanq
    test
    why rust not impl Default trait for any size array
    but impl Debug/Clone/Eq trait for any size array
    what is the difference between them
    tanriol
    @tanriol:matrix.org
    [m]
    @Itanq: Yes, this is an unfortunate difference. The problem is that an implementation of Default for [T; N] of any size would require T: Default and thus would conflict with existing impl<T> Default for [T; 0] that does not require that ("because it does not need to create any T").
    MCF
    @mcf-rocks
    what is type is rust enum implemented as?