Search
Treedome 0.5.0: Local Encrypted Notes with Modern Features
A local-first, encrypted, note taking application organized in tree-like structures
![treedome](https://programming.dev/pictrs/image/70427692-9a1d-42b4-a0e5-910f3a4e33b5.png?format=webp&thumbnail=256)
cross-posted from: https://programming.dev/post/18265389
>Hello again everyone, Dihar here. It's been a while since the last release of treedome, but here you go! This release is all about UI update, emojis, and bug fixes. Please consult this git diff
for a more detailed changelog https://codeberg.org/solver-orgz/treedome/compare/0.4.5...0.5.0. These are the highlight of the release.
>
> !
>
> * Add emoji picker for title, will show up in tree!
> * Text Editor toolbar is back, now with option to toggle both toolbar and floating menu independently!
> * Checkbox is here! Thanks Mantine UI!
> * You can check the size of each notes by navigating to Escape Menu -> Configure -> Show Note Sizes!
> * Add created/last modified date in notes. Note created before this will not have this field and will set as today's date!
> * Create child note can now be done through dropdown instead of only from shortcuts!
> * Fix bugs of saving empty tree
> * General UI update and more stability for auto scrolling in tree view
> * Documentation update
Debug-time enforcement of borrowing rules, and safety in general.
Another crazy idea I share with this website.
I was developing a game and an engine in Rust, so I was reading many articles, most of which criticize the 'borrow checker'.
I know that Rust is a big agenda language, and the extreme 'borrow checker' shows that, but if it weren't for the checker, Rust would be a straight-up better C++ for Game development, so I thought: "Why not just use unsafe
?", but the truth is: unsafe
is not ergonomic, and so is Refcell<T>
so after thinking for a bit, I came up with this pattern:
let mut enemies = if cfg!(debug_assertions) { // We use `expect()` in debug mode as a layer of safety in order // to detect any possibility of undefined bahavior. enemies.expect("*message*"); } else { // SAFETY: The `if` statement (if self.body.overlaps...) must // run only once, and it is the only thing that can make // `self.enemies == None`. unsafe { enemies.unwrap_unchecked() } };
You can also use the same pattern to create a RefCell<T>
clone that only does its checks in 'debug' mode, but I didn't test that; it's too much of an investment until I get feedback for the idea.
This has several benefits:
1 - No performance drawbacks, the compiler optimizes away the if
statement if opt-level
is 1 or more. (source: Compiler Explorer)
2 - It's as safe as expect()
for all practical use cases, since you'll run the game in debug mode 1000s of times, and you'll know it doesn't produce Undefined Behavior
If it doesn't crash.
You can also wrap it in a "safe" API for convenience:
``` // The 'U' stands for 'unsafe'. pub trait UnwrapUExt { type Target;
fn unwrap_u(self) -> Self::Target; }
impl<T> UnwrapUExt for Option<T> { type Target = T;
fn unwrap_u(self) -> Self::Target { if cfg!(debug_assertions) { self.unwrap() } else { unsafe { self.unwrap_unchecked() } } } } ```
I imagine you can do many cool things with these probably-safe APIs, an example of which is macroquad's possibly unsound usage of get_context()
to acquire a static mut
variable.
Game development is a risky business, and while borrow-checking by default is nice, just like immutability-by-default, we shouldn't feel bad about disabling it, as forcing it upon ourselves is like forcing immutability, just like Haskell does, and while it has 100% side-effect safety, you don't use much software that's written in Haskell, do you?
Conclusion: we shouldn't fear unsafe
even when it's probably unsafe, and we must remember that we're programming a computer, a machine built upon chaotic mutable state, and that our languages are but an abstraction around assembly.
graydon/rust-prehistory: historical archive of rust pre-publication development
historical archive of rust pre-publication development - graydon/rust-prehistory
![GitHub - graydon/rust-prehistory: historical archive of rust pre-publication development](https://programming.dev/pictrs/image/598cb44e-3807-4c9b-84e9-dda693c25703.png?format=webp&thumbnail=256)
Excerpt:
> This is a reconstruction -- extracted and very lightly edited -- of the "prehistory" of Rust development, when it was a personal project between 2006-2009 and, after late 2009, a Mozilla project conducted in private. > > The purposes of publishing this now are: > > - It might encourage someone with a hobby project to persevere > - It might be of interest to language or CS researchers someday > - It might settle some arguments / disputed historical claims
Rust started being developed 18 years ago. This is how it looked until 14 years ago, where I believe the rest of development is on rust-lang/rust. The first Rust program looks completely different than the Rust we know today.
A table of publicly available Arena crates and their features
Sometimes you just really need an arena. Sometimes for performance reasons, other times for lifetime-related reasons. In their most basic forms, they're just a vec with some extra guarantees. However, it's those extra guarantees that matter. I've found myself looking for the right kind of arena too ...
For a technical discussion of using arenas for memory allocation with an example implementation, see gingerBill's Memory Allocation Strategies - Part 2: Linear/Arena Allocators
COSMIC ALPHA 1 Released (Desktop Environment Written In Rust From System76)
System76 computers empower the world's curious and capable makers of tomorrow
How do I parse the escape characters of the content of a string literal input with nom?
So, I'm basically trying to parse a string literal with nom. This is the code I've come up with:
```rust use nom::{ bytes::complete::{tag, take_until}, sequence::delimited, IResult, };
/// Parses string literals. fn parse_literal<'a>(input: &'a str) -> IResult<&'a str, &'a str> { // escape tag identifier is the same as delimiter, obviously let escape_tag_identifier = input .chars() .nth(0) .ok_or(nom::Err::Error(nom::error::Error::new( input, nom::error::ErrorKind::Verify, )))?;
let (remaining, value) = delimited( tag(escape_tag_identifier.to_string().as_str()), take_until(match escape_tag_identifier { '\'' => "'", '"' => "\"", _ => unreachable!("parse_literal>>take_until branched into unreachable."), }), tag(escape_tag_identifier.to_string().as_str()), )(input)?;
Ok((remaining, value)) }
#[cfg(test)] mod literal_tests { use super::*;
#[rstest] #[case(r#""foo""#, "foo")] #[case(r#""foo bar""#, "foo bar")] #[case(r#""foo \" bar""#, r#"foo " bar"#)] fn test_dquotes(#[case] input: &str, #[case] expected_output: &str) { let result = parse_literal(input); assert_eq!(result, Ok(("", expected_output))); }
#[rstest] #[case("'foo'", "foo")] #[case("'foo bar'", "foo bar")] #[case(r#"'foo \' bar'"#, "foo ' bar")] fn test_squotes(#[case] input: &str, #[case] expected_output: &str) { let result = parse_literal(input); assert_eq!(result, Ok(("", expected_output))); }
#[rstest] #[case(r#""foo'"#, "foo'")] #[case(r#"'foo""#, r#"foo""#)] fn test_errs(#[case] input: &str, #[case] expected_err_input: &str) { let result = parse_literal(input); assert_eq!( result, Err(nom::Err::Error(nom::error::Error::new( expected_err_input, nom::error::ErrorKind::TakeUntil ))), ); } } ```
> Note: The example uses rstest
for tests.
Although it looks a little bit complex, actually, it is not. Basically, the parse function is parse_literal
. The tests are separated for double quotes and single quotes and errors.,
When you run the tests, you will realize first and second cases for single and double quotes run successfully. The problem is with the third case of each: #[case(r#""foo \" bar""#, r#"foo " bar"#)]
for test_dquotes
and #[case(r#"'foo \' bar'"#, "foo ' bar")]
for test_squotes
.
Ideally, if a string literal is defined with single quotes and has single quotes in its content, the single quotes can be escaped with single quotes again. Same goes for double quotes as well. To demonstrate in a pseudocode:
plain "foo ' bar" // is ok "foo \" bar" // is ok "foo " bar" // is err 'foo " bar' // is ok 'foo \' bar' // is ok 'foo ' bar' // is err
Currently, in the code, I take characters until the delimiter with take_until
, which reaches to the end of the input
, which, let's say, in this case, is guaranteed to contain only and only the string literal as input. So it's kind of okay for first and second cases in the tests.
But, of course, this fails in the third cases of each test since the input
has the delimiter character early on, finishes early and returns the remaining.
This is only for research purposes, so you do not need to give a fully-featured answer. A pathway is, as well, appreciated.
Thanks in advance.
System76 with Jeremy Soller | Rust in Production Podcast S02 E07 by corrode Rust Consulting | 2024-07-25
Many devs dream of one day writing their own operating system. Ideally in their favorite language: Rust. For many of us, this dream remains just that: a dream. Jeremy Soller from System76, however, didn't just contribute kernel code for Pop!_OS, but also started his own operating system, RedoxOS, wh...
![System76 with Jeremy Soller - Rust in Production Podcast | corrode Rust Consulting](https://programming.dev/pictrs/image/e95fea92-5fd1-4fca-a82b-1bdc0eba903b.png?format=webp&thumbnail=256)
> Many devs dream of one day writing their own operating system. Ideally in their favorite language: Rust. For many of us, this dream remains just that: a dream. > > Jeremy Soller from System76, however, didn't just contribute kernel code for Pop!_OS, but also started his own operating system, RedoxOS, which is completely written in Rust. One might get the impression that he likes to tinker with low-level code! > > In this episode of Rust in Production, Jeremy talks about his journey. From getting hired as a kernel developer at Denver-based company System76 after looking at the job ad for 1 month and finally applying, to being the maintainer of not one but two operating systems, additional system tools, and the Rust-based Cosmic desktop. We'll talk about why it's hard to write correct C code even for exceptional developers like Jeremy and why Rust is so great for refactoring and sharing code across different levels of abstraction.
Listen to Rust in Production Podcast S02 E07
Jiff is a new date-time library for Rust that encourages you to jump into the pit of success
A date-time library for Rust that encourages you to jump into the pit of success. - BurntSushi/jiff
![GitHub - BurntSushi/jiff: A date-time library for Rust that encourages you to jump into the pit of success.](https://programming.dev/pictrs/image/262c8c25-6a88-4d5f-aa40-564222207ca9.png?format=webp&thumbnail=256)
Anyone looking for a fun small rust project? Create a crate for cleaning urls, based on the ClearUrls project
cross-posted from: https://lemmy.ml/post/18162485
> This would entail:
>
> - Pulling in the ClearUrls rules as a git submodule.
> - Reading / transforming the json there into Rust structs.
> - Creating a Rust crate that runs a .clean(input_url) -> String
>
> Lemmy issue: https://github.com/LemmyNet/lemmy/issues/4905
diesel_async 0.5 released, with SQlite support
Added type diesel_async::pooled_connection::mobc::PooledConnection MySQL/MariaDB now use CLIENT_FOUND_ROWS capability to allow consistent behaviour with PostgreSQL regarding return value of UPDATe ...
![Release Diesel-Async 0.5.0 · weiznich/diesel_async](https://feddit.org/pictrs/image/5db86709-c28a-443d-a9c6-0e542c984a21.png?format=webp&thumbnail=256)
> - Added type diesel_async::pooled_connection::mobc::PooledConnection
> - MySQL/MariaDB now use CLIENT_FOUND_ROWS
capability to allow consistent behaviour with PostgreSQL regarding return value of UPDATe
commands.
> - The minimal supported rust version is now 1.78.0
> - Add a SyncConnectionWrapper
type that turns a sync connection into an async one. This enables SQLite support for diesel-async
> - Add support for diesel::connection::Instrumentation
to support logging and other instrumentation for any of the provided connection impls.
> - Bump minimal supported mysql_async
version to 0.34
>
> A special thanks goes to @momobel and Wattsense for contributing the SyncConnectionWrapper
implementation.
>
> To support future development efforts, please consider sponsoring me on GitHub.
>
> Full Changelog: v0.4.0...v0.5.0
Ferris is now on the Fediverse Canvas!
![](https://programming.dev/pictrs/image/84d19ab6-3c77-4806-97d7-b49ebf78a1b2.png?format=webp&thumbnail=128)
![](https://programming.dev/pictrs/image/84d19ab6-3c77-4806-97d7-b49ebf78a1b2.png?format=webp)
I hope this slightly off-topic post is ok here. Today the Fediverse Canvas 2024 event begun and I thought it would be nice to add Ferris to the canvas. I started with a couple of pixels, but after a while I got distracted with other things. When I came back, I found that some of you have already finished it 🦀
Btw. Ferris sits on top of the Godot logo (bottom and slightly right).
Should RustSec (Advisory Database and Cargo tools) be embraced at the foundational level and made a "mandatory best practice"?
Security advisory database for Rust crates published through https://crates.io
Hi all,
ref: https://programming.dev/post/16349359
I agree with all the criticism about the author, the intentions, and the points in the article, expressed in the ref. thread. I also think the author highlights a serious issue (if we leave "selling the book", cheap criticism, and sensationalism aside). While nothing new for most developers, the article has spawned a personal rabbit hole of discovery, starting from supply chain attacks.
I am still very early in my process of learning Rust (still reading The Book) and self-taught software engineering in general, and the journey the article has spawned was very educational to me. I've learned about securing software and being mindful across the whole SDLC[1], AppSec, DevSec, OWASP, SLSA[2] Socket[3], GitHub Advanced Security, and many more tools and guidelines. Last of which is RustSec[4]. Which quenched my thirst and closed that personal rabbit hole. It has opened a different can of worms though.
While endemic to any non-monolithic ecosystem and only part of the "big security picture", supply chain is possibly the major player across the spectrum. Comparable to "the legacy issue" of stagnating systems and infrastructures, open to exploits as old as the Sun.
Now, while I am aware that security is a process, not a product and that this is easier said than done: I wonder if tools like RustSec should be embraced at the foundational level and made a "mandatory best practice". RustSec tools integrate with an up to date security advisory database and Cargo. They can also be deployed as GitHub Actions.
Because I am sure this is not all roses: I agree that (for example) dependabot is seen as a major annoyance more than a useful tools for a number of reasons, and that RustSec could spark the same kind of thoughts. However, it could be a great stepping stone of the security process.
I am aware I may be being too idealistic here, but the process has to start from somewhere and stagnating on "dogmas" ain't helping either.
Please be kind in your replies.
Cheers
[1] https://www.youtube.com/watch?v=hDvz8KivY_U [2] https://slsa.dev [3] https://socket.dev [4] https://rustsec.org
Rust has a HUGE supply chain security problem | Sylvain Kerkour | July 2, 2024
July 2, 2024
Sylvain Kerkour writes:
> Rust adoption is stagnating not because it's missing some feature pushed by programming language theory enthusiasts, but because of a lack of focus on solving the practical problems that developers are facing every day. > > ... no company outside of AWS is making SDKs for Rust ... it has no official HTTP library. > > As a result of Rust's lack of official packages, even its core infrastructure components need to import hundreds of third-party crates. > > - cargo imports over 400 crates. > > - crates.io has over 500 transitive dependencies. > > ...the offical libsignal (from the Signal messaging app) uses 500 third-party packages. > > ... what is really inside these packages. It has been found last month that among the 999 most popular packages on crates.io, the content of around 20% of these doesn't even match the content of their Git repository. > > ...how I would do it (there may be better ways): > > A stdx (for std eXtended) under the rust-lang organization containing the most-needed packages. ... to make it secure: all packages in stdx can only import packages from std or stdx. No third-party imports. No supply-chain risks.
[stdx packages to include, among others]:
> gzip, hex, http, json, net, rand
Read Rust has a HUGE supply chain security problem
---
Submitter's note:
I find the author's writing style immature, sensationalist, and tiresome, but they raise a number of what appear to be solid points, some of which are highlighted above.
I've created a CLI tool to download Rust web books as EPUB
Rust Book to EPUB converter. Contribute to mawkler/rust-book-to-epub development by creating an account on GitHub.
![GitHub - mawkler/rust-book-to-epub: Rust Book to EPUB converter](https://programming.dev/pictrs/image/aecf9b20-0829-4edf-aef1-02010a3e4f59.png?format=webp&thumbnail=256)
Hi! I've created a CLI tool for downloading Rust web books (like The Rust Programming Language) as EPUB, so that you can easily read them on your e-book reader. The tool is heavily based on this gist and a lot of proompting.
Check it out here: https://github.com/mawkler/rust-book-to-epub
Welcome Eliah, and gitoxide
for GitButler
This month was very productive, just not directly for gitoxide. And it's notably the first month in my recollection where that happened. There must be a special reason for it, and bluntly, it's jus...
![[April] Welcome Eliah, and `gitoxide` for GitButler · Byron gitoxide · Discussion #1375](https://programming.dev/pictrs/image/2af8ab36-f7a3-4095-af9b-03ca3738d2d9.png?format=webp&thumbnail=256)
New crate: derive_typst_intoval
Hey all!
I've just published a small crate, and would like to take the occasion to not only announce this, but also make typst
better known in the rust community, because I think it's awesome :)
What does this do?
It provides a derive macro to derive typst::foundations::IntoValue
for a struct.
Why would I want that?
If you're using typst
as a library, chances are you want to get data into your documents. Rather than using a templating library or rolling your own, I'd suggest using inputs
(I'm still excited being made aware of that!), which implies making a Value
out of your data. typst_macros
provides the possibility to derive Cast
, which includes the treasured IntoValue
... for enums. This is a gap somewhat closed by this crate.
So what about this typst?
typst
is a typesetting system (akin to LaTeX) written in Rust. The core and cli are licensed freely, and it is very useable up to the point that I personally don't use latex anymore, but have switched to typst. I'm personally ultra-fond of the ability to use typst as a library, which makes it perfect for apps that want to produce high-quality documents from user-provided data.
Any questions, comments, criticism, code reviews welcome! Also, give typst a shot.
Rusty Playdate - Toolset and API
I’m working on a big project in #Rust, there is toolset and API for #Playdate.
All going great, moving to stabilization step by step, but so tired of looking at the dull amount ⭐️.
Websurfx 1.15.0 release
![](https://programming.dev/pictrs/image/e8085ad0-0290-4046-94e6-bc2129d4e89f.png?format=webp&thumbnail=128)
![](https://programming.dev/pictrs/image/e8085ad0-0290-4046-94e6-bc2129d4e89f.png?format=webp)
Hello again!!
Sorry for the big delay in the announcements. I know it has been a long time I have not made any announcements, but I will try my best next time this doesn't happen again.
So, through the medium of this post I would like to share with you all the v1.15.0
major release version of the websurfx
project which was released on the 25th of March.
If you are new, and you don't know what is websurfx
then I would suggest taking a look at my previous post here:
https://programming.dev/post/2678496
Which covers in depth about what the project is and why it exists.
Credits
Before I share with you the changelog
, what this release version means and a preview on what we are planning to work on for the next major release v2.0.0
. I would first like to thank all our contributors and maintainers because of whom this was all possible. Specially I would like to thank spencerjibz, ddotthomas and evanyang1 who have been invaluable to the project. Also, Websurfx
would not have been possible without alamin655 and xffxff early involvement.
! Thanks 💖 to all the people involved in the project
Now, let's dive straight into what this release version actually means.
What does this release version means
This new release version v1.15.0
introduces the new ranking algorithm for search results on the search page which ranks the results based on the relevancy to the user's search query.
Changelog
The changelog of all the changes can be found here:
https://github.com/neon-mmd/websurfx/releases/tag/v1.15.0
Preview of the goals for the next major release
- Different levels of privacy to choose from with the help of rust's conditional compiling features (In progress).
- Even more engines will be supported.
- Categories would be added to search results like images, news, etc.
- More themes will be provided by default
- More animations for the websurfx frontend will be supported.
- Multi language support would be added.
- I2p and tor support will be provided.
- Reduce animations would be added for those who don't want animations and effects on the frontend.
- And lots more ✨.
efs, a no_std library for filesystems
efs is a recently published no-std library which provides an OS and architecture independent implementation of some UNIX filesystems in Rust.
Currently only the ext2 filesystem is directly implemented, but I will soonly work on other filesystems!
It's still young so it may contain bugs, but it's hugely tested so that it does not happen.
Some of the features provided :
-
no_std support (enabled by default)
-
General interface for UNIX files and filesystems
-
read/write regular files
-
retrieve, add and remove directory entries directly from a path and a current working directory.
I hope you will find this useful! If you have any remark, idea or issue, do not hesitate to ask here or to submit an issue!