• 3 Posts
  • 72 Comments
Joined 1 year ago
cake
Cake day: July 9th, 2023

help-circle

  • Regarding Cargo.lock, the recommendation always was to include it in version control for application/binary crates, but not library ones. But tendencies changed over time to include it even for libraries. If a rust-toolchain file is tracked by version control, and is pinned to a specific stable release, then Cargo.lock should definitely be tracked too [1][2].

    It’s strictly more information tracked, so there is no logical reason not to include it. There was this concern about people not being aware of --locked not being the default behaviour of cargo install, giving a false sense of security/reliability/reproducibility. But “false sense” is never a good technical argument in my book.

    Anyway, your crate is an application/binary one. And if you were to not change the "*" dependency version requirement, then it is almost guaranteed that building your crate will break in the future without tracking Cargo.lock ;)






  • Next Day Edit: Sorry. Forgot to use my Canadian Aboriginal syllabics again. Because apparently it’s too hard to admit HTML-sanitizing source markdown was wrong!

    One thing that irks me in these articles is gauging the opinion of the “Rust community” through Reddit/HN/Lemmy😉/blogs… etc. I don’t think I’d be way off the mark when I say that these platforms mostly collectively reflect the thoughts of junior Rustaceans, or non-Rustaceans experimenting with Rust, with the latter being the loudest, especially if they are struggling with it!

    And I disagree with the argument that poor standard library support is the major issue, although I myself had that thought before. It’s definitely current lack of language features that do introduce some annoyances. I do agree however that implicit coloring is not the answer (or an answer I want to ever see).

    Take this simple code I was writing today. Ideally, I would have liked to write it in functional style:

        async fn some_fn(&self) -> OptionᐸMyResᐸVecu8ᐳᐳᐳ {
            (bool_cond).then(|| async {
                // ...
                // res_op1().await?;
                // res_op2().await?;
                // ...
                Ok(bytes)
            })
        }
    

    But this of course doesn’t work because of the opaque type of the async block. Is that a serious hurdle? Obviously, it’s not:

        async fn some_fn(&self) -> OptionᐸMyResᐸVecu8ᐳᐳᐳ {
            if !bool_cond {
                return None;
            }
    
            let res = || async {
                // ...
                // res_op1()?;
                // res_op2()?;
                // ...
                Ok(bytes)
            };
    
            Some(res().await)
        }
    

    And done. A productive Rustacean is hardly wasting time on this.

    Okay, bool::then() is not the best example. I’m just show-casing that it’s current language limitations, not stdlib ones, that are behind the odd async annoyance encountered. And the solution, I would argue, does not have to come in the form of implicit coloring.



  • I would bad mouth Axum and Actix just because of the overhype. But then, the latter is powering this very platform, and the former is used in the federation crate examples 😉

    So let me just say that I tried poem and it got the job done for me. Rusty API. Decent documentation. And everything is in one crate. No books, extension crates, and towers of abstractions needed.

    I try to avoid tokio stuff in general for the same reason, although a compatible executor is unfortunately often required.


  • From your list, I use bat, exa and rg.

    delta (sometimes packaged as git-delta) deserves a mention. I use it with this git configuration:

    [core]
      # --inspect-raw-lines=false fixes issue where some added lines appear in bold blue without green background
      # default minus-style is 'normal auto'
      pager = "delta --inspect-raw-lines=false --minus-style='syntax #400000' --plus-style='syntax #004000' --minus-emph-style='normal #a00000' --plus-emph-style='normal #00a000' --line-buffer-size=48 --max-line-distance=0.8"
    
    [interactive]
      diffFilter = "delta --inspect-raw-lines=false --color-only --minus-style='syntax #400000' --plus-style='syntax #004000' --minus-emph-style='normal #a00000' --plus-emph-style='normal #00a000' --line-buffer-size=48 --max-line-distance=0.8"
    
    [delta]
      navigate = true  # use n and N to move between diff sections
      light = false    # set to true if you're in a terminal w/ a light background color (e.g. the default macOS terminal)
    
    [merge]
      conflictstyle = diff3
    


  • Note: the ᐸᐳ characters used below are Canadian Aboriginal syllabics because Lemmy devs haven’t fixed broken input sanitization yet.


    Well, getters are not an official concept in Rust. You can do whatever works best in your case.

    Just worth pointing out that a method with a return value of OptionVecStringᐳᐳ wouldn’t be really a getter, as you must be constructing values, or moving ownership, or cloning. None of these actions conceptually belong to a getter.

    Also, you should be clear on the what the Option abstraction means. Does it mean the vector is empty? Does it mean the vector does not exist or some sort of null (FFI ore serialization contexts)? And make sure the code does what you expect it to do.


  • Note: the ᐸᐳ characters used below are Canadian Aboriginal syllabics because Lemmy devs haven’t fixed broken input sanitization yet.


    A vec and a string are basically the same thing (a series of bytes)

    Everything is a series of bytes! I thought you were going to mention that both are fat pointers. But that “series of bytes” description is quite weird.

    This makes handling it much easier because you can still iterate over it

    This is not a valid consideration/objection, as Options are iterable and you can flatten them:

    fn main() {
      let v = vec![1,2,3];
      for n in Some(&v).into_iter().flatten() {
        eprintln!("{n}");
      }
      for n in None::ᐸ&Veci32ᐳᐳ.into_iter().flatten() {
        eprintln!("{n}");
      }
    }
    

    This might involve the compiler making an allocation of an empty array but most of them (gcc, ghc) will now what you are doing and optimize the null check on the empty array to a bool check

    This paragraph appears to be out of place in the context of a Rust discussion.








  • Besides being overhyped basic tech where way more useful and practical solutions existed for decades (Freenet existed since year 2000 btw, and Tahoe-LAFS since 2007), there is nothing private about IPFS. This is a dangerous message to purport.

    IPFS is as practically useful as NFTs. No wonder the two crowds connected well!

    iroh is an attempt to create a useful and practical IPFS. But none of the bigger practical features is implemented yet. And the design itself doesn’t appear to be finalized. I’m willing to give iroh a chance, although the close proximity to the IPFS crowd doesn’t fill one with confidence.