今日已更新 84 条资讯 | 累计 37333 条内容
关于我们

标签:#Rust

找到 447 篇相关文章

产品设计

Forms, payloads, and live inputs in Fitz LiveViews

TL;DR — Events in Fitz LiveViews carry data three ways: a click payload ( data-flv-value-* ) tags a button with the value it should send; a form submit ( data-flv-submit ) reads the form's named inputs; and a live value ( @input / @change ) delivers a control's current value in payload["value"] . All three land in the same place — a payload map your handler reads. This post builds a live name list (add / remove / count) that runs both server-rendered and as WebAssembly. (Part 3 of the FitzLiveViews series.) Parts 1 and 2 covered the pitch and the counter. A counter only reads +1 / -1 — no data flows in . Real UIs take input: text, selections, form fields. Here's how that data reaches your handlers. The payload Every event handler has a payload in scope — a Map<Str, Str> . The three mechanisms below all fill it; your handler reads it with payload["key"] (guard with payload.has("key") ): 1. Click payload — a button that carries a value Tag any element with data-flv-value-<key>="{expr}" , and when a data-flv-click on it (or an ancestor) fires, that value rides along: <button data-flv-click= "remove" data-flv-value-item= "{it}" > × </button> event remove () { if ( payload . has ( " item " )) { let target = payload [ " item " ] names = names . filter ( fn ( it ) => it != target ) } } The delete button knows which row it is because the row's value is stamped on it. No IDs threaded through a callback, no closure capture. 2. Form submit — the whole form at once data-flv-submit="handler" on a <form> reads each named input into the payload on submit; data-flv-clear resets a field afterward: <form data-flv-submit= "add" > <input name= "item" placeholder= "Add a name" data-flv-clear /> <button type= "submit" > Add </button> </form> event add () { if ( payload . has ( " item " )) { let n = payload [ " item " ] if ( n != "" ) { names . push ( n ) } } } payload["item"] is the input's value at submit time. No preventDefault , no FormData , no fetch . 3. Live value — @input / @chang

2026-08-11 原文 →
AI 资讯

Write down every guarantee before you write any code

Here is every promise a to-do list makes. VARIABLE tasks Init == tasks = [i \in Ids |-> "absent"] Add(i) == tasks[i] = "absent" /\ tasks' = [tasks EXCEPT ![i] = "open"] Complete(i) == tasks[i] = "open" /\ tasks' = [tasks EXCEPT ![i] = "done"] Reopen(i) == tasks[i] = "done" /\ tasks' = [tasks EXCEPT ![i] = "open"] Delete(i) == tasks[i] # "absent" /\ tasks' = [tasks EXCEPT ![i] = "absent"] ClearCompleted == /\ \E i \in Ids : tasks[i] = "done" /\ tasks' = [i \in Ids |-> IF tasks[i] = "done" THEN "absent" ELSE tasks[i]] Not a summary. Not the important ones. All of them. A task cannot go from absent straight to done. Clearing completed items leaves the open ones alone. You cannot delete something that was never there. Nine lines, and when you've read them you have read the entire contract. Now go find that list for the system you work on. You can't. It doesn't exist. It's distributed across a test suite that asserts outcomes rather than rules, some validation scattered through handlers, and the memory of whoever's been there longest. The guarantees are real — your users depend on every one of them — and there is no file you can open to see them. That's the gap I want to talk about, because you can close it in an afternoon, and because something has changed recently that makes closing it pay for itself. The prime mark and two operators That's most of the syntax, so let's get it out of the way. tasks' means "tasks, in the next state." /\ is and . \E is "there exists." A definition like Complete(i) is a formula relating the current state to the next one — read it out loud: the task is open, and afterwards it is done. That's it. That's the language, near enough, for this purpose. The real file adds about eight lines of scaffolding around what you saw: a module header, a TypeOK saying a task is always in exactly one of the three states, and the two lines that tie the actions together — Next == \/ \E i \in Ids : Add(i) \/ Complete(i) \/ Reopen(i) \/ Delete(i) \/ ClearComplete

2026-08-11 原文 →
开发者

140 Bugs Were Hiding in One Function, and My Tests Couldn't See Any of Them

Anyone can port a library. Point a translator at the source, clean up the output, get it to compile, and you have something that looks like a port. The actual engineering problem is different and much harder: proving that the new code means the same thing as the old code, across thirty algorithms, hundreds of edge cases, and a test suite written by people who were not thinking about you. This is the story of porting textdistance , a Python library for measuring string similarity, to Rust. The result is textdistance-rs . The porting took a fraction of the time. Everything else: the differential fuzzing, the 140 divergences, the 35 year old threshold I violated, the floating-point drift at the 15th decimal place, is what this writeup is actually about. Thirty algorithms and one architectural bet The original textdistance covers a lot of ground: edit-based distances (Levenshtein, Damerau-Levenshtein, Hamming, Jaro-Winkler), token-based measures (Jaccard, Sørensen-Dice, cosine, Tversky), sequence-based methods (LCS, Ratcliff-Obershelp), phonetic algorithms (MRA, Editex), and compression-based distances built on normalized compression distance. Over thirty algorithms in total, all reimplemented in Rust. But before writing a single algorithm, I had to make the decision that shaped everything downstream: how does the existing Python test suite (397 tests I did not write) talk to the Rust code? The obvious answer is PyO3: wrap every algorithm in a #[pyclass] , build a native extension, and the Python tests import Rust directly. The answer I chose instead was a subprocess CLI. The Rust core is a standalone binary that speaks JSON over stdin/stdout, and a thin Python adapter shells out to it: // The entire cross-language surface is one struct. #[derive(Deserialize)] struct Request { algorithm : String , s1 : String , s2 : String , qval : Option < usize > , external : Option < bool > , } fn dispatch ( req : & Request ) -> Response { match req .algorithm .as_str () { "hamming"

2026-08-10 原文 →
AI 资讯

How I Built a Counter Program in Rust and Learned to Trust My Tests

Building smart contracts on Solana using Rust and the Anchor framework requires a mindset shift from traditional Web2 backends. This week, I built a counter program, broke it on purpose, and used my test suite to verify that my security constraints were truly load-bearing. Here is how the program works under the hood and why every test in the suite exists. The Initialize Accounts Struct In Anchor, security boundaries are enforced before your instruction logic ever runs. The Initialize context defines three main accounts: counter : Initialized as a new on-chain account allocated with exact bytes (8 bytes for Anchor's discriminator, 32 for the authority's public key, and 8 for the count value). authority : Marked as a mutable signer who pays the account creation rent. system_program : The native Solana System Program required to execute account creation. Handler Logic & Constraints Because Anchor handles account creation and validation in the background, handler logic remains minimal. Initialize Handler The initialize handler receives the context, sets the counter account's authority field to match the transaction signer's public key, and sets the initial count state to zero. Increment Instruction with Constraints For the increment logic, Anchor uses an account constraint: has_one = authority , directly on the account context. This guarantees that the key in counter.authority matches the signer's wallet before any custom code executes. If an unauthorized wallet attempts to trigger an increment, Anchor rejects the transaction immediately at the constraint level. Testing the Happy and Failure Paths To prove these security checks work, I wrote unit tests for both valid execution and unauthorized attempts using LiteSVM. 1. Happy Path: Successful Initialization The Test: Executes the initialize instruction and asserts that the fetched account's count value equals zero. Why it exists: If space allocation fails or account deserialization breaks, this test fails because the o

2026-08-09 原文 →
AI 资讯

I built RepoTrek: a terminal-first GitHub source browser in Rust

I built RepoTrek , a terminal-first GitHub source browser written in Rust. GitHub: https://github.com/yuna-r/repotrek crates.io: https://crates.io/crates/repotrek The basic idea is simple: I wanted a comfortable way to deeply explore GitHub repositories without constantly switching between the browser, terminal, and editor. RepoTrek is not intended to replace Git clients such as git , lazygit , tig , or gitui . Its focus is different: Git client ↓ operate on a repository RepoTrek ↓ explore and read a repository Why I built it When reading open-source projects on GitHub, I often move through a sequence like this: Code ↓ Blame ↓ Commit ↓ Diff ↓ File history ↓ Another file GitHub's web interface is excellent, but when I spend a long time reading source code, I prefer staying in the terminal and using the keyboard. So I started building a TUI specifically around source code exploration . No clone required You can open a repository directly from GitHub. For example: rust-lang/rust or: torvalds/linux RepoTrek retrieves the repository information through GitHub APIs, so you don't need to clone the entire repository just to inspect it. This is especially convenient for quickly looking through large projects. Features RepoTrek currently includes: Repository tree browsing Source code viewer with line numbers Syntax highlighting Dark / Light themes Commit history Commit diffs File history Git blame Branch switching File search Repository-wide code search Symbol navigation Definition search Pull Requests Issues GitHub Actions Releases Keyboard-based text selection and copy Source/diff wrapping HTML export for printing The interface is designed to make moving between these views fast without leaving the terminal. Source code browsing The main view works like a terminal-native repository browser. src/ ├── app.rs ├── auth.rs ├── export.rs ├── highlight.rs ├── provider/ └── ui/ Open a file and RepoTrek displays it with line numbers and syntax highlighting. Common languages such as

2026-08-09 原文 →
AI 资讯

Stop Chasing Symptoms: How We Built an Autonomous Root Cause Analysis Engine in Rust 🦀

It’s 2:15 AM. Your phone buzzes aggressively. 🚨 You jump out of bed, open your laptop with half-closed eyes, and join an emergency incident response call. Your team’s Slack channel is exploding: ⚠️ [ALERT] Payment API 500 Error Rate > 15% ⚠️ [ALERT] Redis Latency Timeout (>5000ms) ⚠️ [ALERT] Node-04 CPU Saturation (98%) You spend the next 2 hours manually connecting the dots: querying Prometheus metrics, scrolling through endless Loki logs, cross-referencing Tempo traces, and checking recent ArgoCD deployments. Eventually, you uncover the truth: Deployment #218 , pushed right before midnight, introduced a subtle memory leak that triggered GC pressure, spiked CPU, starved the Redis connection pool, and knocked down the Payment API. Sounds familiar? 😅 💥 The Problem: Observability Shows Symptoms , Not Causes Modern observability tools like Grafana, Prometheus, Loki, and Jaeger are fantastic at collecting metrics, logs, and traces. But they suffer from one fundamental design limitation: They tell you WHAT is breaking, but leave you to figure out WHY it broke. When a microservice fails in Kubernetes, it triggers a domino effect ( cascading failure ): Deployment #218 (Memory Leak) │ ▼ Garbage Collection Pressure │ ▼ CPU Saturation (98%) │ ▼ Redis Connection Timeout │ ▼ API Gateway Retry Storm │ ▼ Payment Service Down (HTTP 500) Traditional alerting floods you with alerts for the bottom 4 nodes (the symptoms), leaving SREs and DevOps engineers stuck sifting through noise during high-stakes outages. 💡 Introducing IRCAE: Autonomous Root Cause Engine To solve this, we are building IRCAE (Intelligent Root Cause Analysis Engine) —an open-source, enterprise-grade platform designed to turn raw telemetry into autonomous causal reasoning . Instead of asking SREs to correlate telemetry manually, IRCAE automatically answers: "Why did the system fail?" in less than 10 seconds. 🌟 Key Highlights 🚀 Written in Rust (Axum + Tokio) : Built for high-throughput, near-bare-metal performance wi

2026-08-09 原文 →
AI 资讯

ratatop: the process table, and the parentheses that ruin everything

Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback. CPU, memory, disks and network were all "read a file, do some arithmetic, draw it". This one is different. It reads about 400 directories every tick, and it is the first box you can actually interact with. There is one bug in here that I would bet real money most /proc parsers have shipped at some point. Let me start there. The parentheses that ruin everything Here is a line from /proc/[pid]/stat : 125045 (cat) R 125025 125045 125025 0 -1 4194304 92 0 0 0 11 22 0 0 20 0 7 0 ... Space separated. Field 1 is the pid, field 2 is the process name in parentheses, field 14 is user time, field 15 is system time, field 20 is thread count, field 24 is resident memory. So you split on whitespace and index into the result. Obvious. Works perfectly. Until someone runs a process called my (weird) app . 42 (my (weird) app) S 1 42 1 0 -1 0 0 0 0 0 5 5 0 0 20 0 3 0 ... That name is three whitespace-separated tokens, so every field after it shifts by two. Your thread count is now reading someone's page fault counter. Your memory is reading a scheduling priority. Nothing crashes. The numbers are just quietly, confidently wrong. And the process name is fully user-controlled. Anyone can rename a thread to whatever they like. The fix is to not split the whole line at all. Find the last closing parenthesis, take the name from between the first ( and that, and only then split what remains: fn parse_stat ( raw : & str ) -> Option < Stat > { let open = raw .find ( '(' ) ? ; let close = raw .rfind ( ')' ) ? ; let name = raw .get ( open + 1 .. close ) ? .to_string (); // Fields resume at `state`, which is field 3 in the man page's numbering. let fields : Vec <& str > = raw .get ( close + 1 .. ) ? .split_whitespace () .collect (); let field = | number : usize | -> u64 {

2026-08-08 原文 →
AI 资讯

[Advanced Rust] 2.6. API Design Principles of Flexibility Pt.2 - Object Safety, API Design, and Generic Trait Methods

2.6.1. Object Safety When defining a trait, whether it is object-safe is also part of the unstated contract. Object safety is a concept in Rust related to trait objects . It determines whether a trait can be dynamically dispatched, that is, whether it can be used in the form of dyn Trait . Traits That Are Object-Safe Must Satisfy the Following Conditions (Based on RFC 255) All supertraits must also be object-safe If a trait inherits from other traits, then those supertraits must also be object-safe. It must not require Sized A trait cannot use Sized as a supertrait, meaning it cannot contain a Self: Sized bound, because the size of a trait object is unknown at compile time. It cannot have associated constants . It cannot have associated types with type parameters . All associated functions (methods) must satisfy one of the following rules : Dispatchable functions : They cannot have any type parameters, though lifetime parameters are allowed. They must be methods, and Self may only appear in receiver positions such as: &self &mut self Box<Self> Rc<Self> Arc<Self> Pin<P> (where P is one of the types above) They cannot require Self: Sized , otherwise the trait would only be usable for types with known size and object safety would be broken. Explicitly non-dispatchable functions : They may return Self , but such functions must require Self: Sized , so they cannot be called on trait objects and can only be used with concrete types. If you cannot remember all of the above, just remember object safety describes whether a trait can be safely turned into a trait object . What Object Safety Does If a trait is object-safe, meaning it satisfies all of the conditions above, then we can use dyn Trait to treat different types that implement the trait as a single generic type. If it is not object-safe, the compiler will prevent you from using dyn Trait . Object Safety and API Design When designing APIs, it is recommended to make traits object-safe, even if that slightly reduces con

2026-08-07 原文 →