惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
C
Check Point Blog
腾讯CDC
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
Recent Announcements
Recent Announcements
L
LangChain Blog
Microsoft Azure Blog
Microsoft Azure Blog
小众软件
小众软件
J
Java Code Geeks
博客园_首页
Jina AI
Jina AI
美团技术团队
H
Help Net Security
MyScale Blog
MyScale Blog
Engineering at Meta
Engineering at Meta
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
S
SegmentFault 最新的问题

Hacker News: Show HN

PurrrrrFocus: Pomodoro Timer App - App Store Workflow Engine — Multi-Step Orchestration for Bun RapidPhoto: Pro Photo Editor App - App Store GitHub - DheerG/swarms: Achieve extraordinary results with claude code across a variety of tasks SPICE simulation → oscilloscope → verification with Claude Code — Lucas Gerads Show HN: VCoding – A 5 MB native Windows IDE with no dynamic dependencies Show HN: LLMs don't hallucinate because they're bad at math, it's the format GitHub - Agent-FM/agentfm-core: AgentFM is a peer-to-peer network that turns everyday computers into a decentralized AI supercomputer. AgentFM lets you run massive AI workloads directly across a global mesh of idle CPUs and GPUs. Show HN: Tracking Top US Science Olympiad Alumni over Last 25 Years GitHub - Potarix/agent-hub: One place to talk to all your agents Show HN: Runtime security for AI agents(injection,tool abuse, data exfiltration) GitHub - dubeyKartikay/lazyspotify: Terminal Spotify client for macOS and Linux GitHub - the-banana-tool/king-louie: Easy to use GUI Personal AI Assistant. Win/Linux/Mac. Show HN I made my vacation rental bookable by AI agents–no Airbnb, 0% commission GitHub - basteez/jsf-autoreload: maven plugin to enable hot reload on jsf projects uvm32/hosts/host-gdbstub at main · ringtailsoftware/uvm32 GitHub - labsai/EDDI: Config-driven engine that turns JSON into production-grade AI agents. Multi-agent orchestration, 12+ LLM providers, MCP/A2A protocols, RAG, persistent memory, and enterprise compliance (EU AI Act, GDPR, HIPAA). Built on Quarkus. GitHub - glitchnsec/fortyone-oss: AI Executive Assistant Platform Quickstart | Alien GitHub - muxshed/shed: One stream in, or many. Every destination, simultaneously. No cloud middleman, no per-channel fees, no limits. GitHub - ocrbase-hq/ocrbase: 📄 PDF/IMG ->.MD/JSON Document OCR API for PaddleOCR and GLMOCR. Self-hostable. GitHub - impactjo/home-memory: MCP server that lets your AI assistant remember everything about your home. GitHub - Sets88/dbcls: DbCls is a powerful terminal database client that supports various databases GitHub - neptun2000/heor-agent-mcp GitHub - SeanFDZ/macmind: Single-layer transformer in HyperTalk for the classic Macintosh RollQuation: Math Puzzles - Apps on Google Play GitHub - dropbox/witchcraft Show HN: Agent-cache – Multi-tier LLM/tool/session caching for Valkey and Redis GitHub - opentalon/opentalon: OpenTalon is an open-source platform built from the ground up in Go as a robust alternative to OpenClaw LinkedIn™ 职位抓取工具 - Chrome 应用商店
GitHub - fast/macro-template: Table-driven Rust code temp...
tison · 2026-06-20 · via Hacker News: Show HN

Crates.io Documentation MSRV 1.85 Apache 2.0 licensed Build Status

macro-template provides template!, a procedural macro for generating repeated Rust code from compact, table-driven inputs.

Motivation

macro-template resulted from a ScopeDB code refactor. ScopeDB has used match-template for variant/type match arms and macro_find_and_replace for repeating Rust fragments over type lists. While replacing them, I found that I wanted the same thing in both places: write the choices once, name the columns, and use those names in Rust syntax. There was no existing macro fitting that shape.

That is the table-driven case template! is built around:

trait ReadLe {
    fn read_le(input: &[u8]) -> Self;
}

macro_template::template! {
    for (Ty, Width) in [
        (u16, 2),
        (u32, 4),
        (u64, 8),
    ] {
        impl ReadLe for Ty {
            fn read_le(input: &[u8]) -> Self {
                Ty::from_le_bytes(input[..Width].try_into().unwrap())
            }
        }
    }
}

assert_eq!(u16::read_le(&[0x34, 0x12]), 0x1234);
assert_eq!(u32::read_le(&[1, 0, 0, 0]), 1);

When looking for existing approaches, I also found seq-macro, which covers a neighboring repetition pattern: range-driven generation, where N in 0..=2 becomes literal tokens like 0, 1, and 2. template! keeps both forms under one syntax: table rows, ranges, #( ... )* for partial repetition, and multiple for clauses for Cartesian products. The examples below expand each case.

Examples

Whole-body repetition

Without splice syntax, the whole template body is repeated once per input row:

trait TypeName {
    const NAME: &'static str;
}

macro_template::template! {
    for (Ty, Name) in [
        (u8, "u8"),
        (u16, "u16"),
        (u32, "u32"),
    ] {
        impl TypeName for Ty {
            const NAME: &'static str = Name;
        }
    }
}

assert_eq!(<u16 as TypeName>::NAME, "u16");

Partial repetition

When only part of a surrounding construct should repeat, put that part in #( ... )*. A single separator token tree can be written before *, such as #( ... ),* for comma-separated output:

fn keyword_code(text: &str) -> Option<u8> {
    macro_template::template! {
        for (Pat, Code) in [
            ("async", 1u8),
            ("await", 2u8),
        ] {
            match text {
                #(Pat => Some(Code)),*,
                _ => None,
            }
        }
    }
}

assert_eq!(keyword_code("async"), Some(1));
assert_eq!(keyword_code("await"), Some(2));
assert_eq!(keyword_code("fn"), None);

When a template contains #( ... )* or #( ... ),*, template variables are substituted only inside the splice body, and the surrounding tokens are emitted once. Surrounding identifiers stay literal, even when they have the same name as a template variable. If a value should vary, place it in the splice body.

#( ..., )* and #( ... ),* are different: the latter does not produce a trailing comma. This matches delimiter repetition in macro_rules!.

Range inputs

Inputs can also be ranges of integers, characters, or bytes. Range inputs are written directly after in, without surrounding brackets. Wrap the range in parentheses when calling a range method such as .rev():

let tuple = ("red", "green", "blue");
let mut fields = vec![];

macro_template::template! {
    for N in (0..3).rev() {
        fields.push(tuple.N);
    }
}

assert_eq!(fields, vec!["blue", "green", "red"]);

This cannot be written using an ordinary for-loop because elements of a tuple can only be accessed by their integer literal index, not by a variable.

Integer ranges preserve the radix, suffix, and shared padding width from their bounds. .strip_prefix() removes the radix prefix before substitution, which is useful when combining range values with paste for identifier generation:

macro_template::template! {
    for N in (0x00A..=0x00C).strip_prefix() {
        paste::paste! {
            enum Pin {
                #( [<Pin N>], )*
            }
        }
    }
}

let _ = (Pin::Pin00A, Pin::Pin00B, Pin::Pin00C);

Cartesian products

Multiple input clauses form a Cartesian product in clause order. This is useful when two or more independent dimensions share the same generated body:

struct Cpu;
struct Gpu;

trait Kernel<T> {
    fn run(input: T) -> T;
}

macro_template::template! {
    for Backend in [Cpu, Gpu],
    for Ty in [f32, f64],
    {
        impl Kernel<Ty> for Backend {
            fn run(input: Ty) -> Ty {
                input
            }
        }
    }
}

assert_eq!(<Gpu as Kernel<f64>>::run(1.5), 1.5);

Minimum Rust version policy

This crate's minimum supported rustc version is 1.85.0.

The current policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if crate 1.0 requires Rust 1.85.0, then crate 1.0.z for all values of z will also require Rust 1.85.0 or newer. However, crate 1.y for y > 0 may require a newer minimum version of Rust.

License

This project is licensed under Apache License, Version 2.0.