Releases: Field-of-Dreams-Studio/hotaru
0.8.2
The first release version for 0.8!
- Client / outpoint runtime: new
Client<TS>for outbound traffic, mirroringServer<TS>. Paired with theoutpoint!macro (client-side counterpart toendpoint!) andrun!/call!invocation-style sugar for one-shot and persistent outbound calls. - Protocol trait reshape: channel-based
open_channel/handle/send, plus per-protocolinstall_channelbridge.type Context: RequestContext<Channel = Self::Channel>pins channel-type alignment. NewChanneltrait +ProtocolFlowgive per-exchange close semantics (HTTP/1 closes the connection; multiplexed protocols may close only the stream). - RequestContext rework:
Defaultsupertrait;type Channelas a type anchor;inject_request/into_responseadded.type Error: ProtocolErroris the single source of truth for chain errors, and now also requiresFrom<std::io::Error>(since the client path surfaces transport-level I/O). Use the newEmptyErrorfor prototypes / no-payload protocols. - Result-typed execution chain: middleware, final handlers,
ExecutionChain::run, andUrlNode::runall returnResult<C, <C as RequestContext>::Error>— no boxing at the chain boundary. - Named access points: every registered endpoint/outpoint has an explicit name.
ProtocolEntry::register(name, path, step_names, binding, config)is the single canonical funnel;Server::url(url, name, ...)/Client::url(url, name, ...)are URL-first. - Instance-based transports:
TransportSpec::Inbound/Outboundreplace the oldAccepter/Connectorshape.TcpInbound::bind(target)andTcpOutbound::build(target)materialize once perServer/Client. - HTTPS feature: new
httpscargo feature on the umbrellahotarucrate forwards tohotaru_http/tls, surfacingHTTPS,TlsTransport,TlsOutboundTarget,TlsClientConfig.HTTPS = Http1Protocol<TlsStream, TlsTransport>. LServer!/LClient!/LUrl!/LPattern!macros: replace the oldLApp!for simplified lazy-static declarations. Default toTcpTransport.- Bug fixes
0.7.7-patch1
- Added utility methods (
get_config,get_static,get_config_or_default,get_static_or_default) to theAppstruct inhotaru_coreto simplify access to configuration and static data in a thread-safe manner, supporting the new database and cache integrations. - Bumped
hotaru_coreversion to 0.7.8 to reflect these new capabilities.
0.7.7
- Fn-style blocks: New syntax
pub fn name(req: HTTP) { ... }forendpoint!andmiddleware!macros (original hotaru blocks syntax preserved) - Client IP access:
req.client_ip(),req.client_ip_only(),req.server_addr()and related methods for accessing socket addresses in handlers - Bug fix for URL routing
Snapshot: 26w02a
A new syntax is introduced:
use hotaru_meta::endpoint;
endpoint! {
APP.url("/api/users"),
pub fn handle_users(req: HTTP) {
text_response("User list")
}
}use hotaru_meta::middleware;
middleware! {
pub fn AuthMiddleware(req: HTTP) {
// Middleware implementation
}
}New syntax is called fn-style blocks, where old syntax still preserved and named hotaru blocks.
First Snapshot!
Access client IP addresses and connection details directly from your handlers:
endpoint! {
APP.url("/api/whoami"),
pub whoami<HTTP> {
// Get client's full socket address (IP + port)
match req.client_ip() {
Some(addr) => text_response(format!("Your address: {}", addr)),
None => text_response("Unknown client"),
}
}
}Available Methods:
| Method | Return Type | Description |
|---|---|---|
client_ip() |
Option<SocketAddr> |
Client's socket address (IP + port) |
client_ip_or_default() |
SocketAddr |
Returns 0.0.0.0:0 if unknown |
client_ip_only() |
Option<IpAddr> |
Just the IP address, no port |
client_ip_only_or_default() |
IpAddr |
Returns 0.0.0.0 if unknown |
server_addr() |
Option<SocketAddr> |
Server's bound address |
remote_addr() |
Option<SocketAddr> |
Alias for client_ip() |
local_addr() |
Option<SocketAddr> |
Alias for server_addr() |
Note: When behind a reverse proxy, client_ip() returns the proxy's address. Use headers like X-Forwarded-For or X-Real-IP to get the original client IP.
0.7.6
[1] Now the worker() function for APP is now useful
The .worker() method now properly configures the number of worker threads for the application. Each App instance creates its own independent tokio runtime with the specified worker count when run() is called. This setting is independent of any outer runtime configuration.
#[tokio::main]
async fn main() {
let app = App::new()
.worker(4) // App runs with 4 dedicated worker threads
.binding("127.0.0.1:3000")
.build();
app.run().await;
}[2] LApp!, LUrl!, and LPattern! macros are available for simplified lazy static declarations
New convenience macros simplify creating lazy static instances with less boilerplate:
use hotaru::prelude::*;
// Old way
pub static APP: SApp = Lazy::new(|| {
App::new().build()
});
// New way with LApp! macro
LApp!(APP = App::new().build());
// Also works for URLs and patterns
LUrl!(HOME_URL = Url::new("/home"));
LPattern!(API_PATTERN = PathPattern::new("/api/*"));The L prefix stands for "Lazy/Load" - these macros automatically wrap your expression in Lazy::new(|| ...) and create a public static with the appropriate type (SApp, SUrl, SPattern).
Benefits:
- Less boilerplate - no manual
Lazy::new(|| ...)wrapper - Clear intent -
LApp!immediately signals "lazy app instance" - Consistent pattern across all lazy static declarations
- Educational - shows the assignment pattern while hiding ceremony
[3] Bug Fixes in hotaru new and hotaru init commands
Fixed template generation issues in the hotaru CLI tool:
- Fixed old macro usage: The generated template now uses the correct
endpoint!macro syntax instead of the old syntax#[url]attribute - Updated to use LApp!: Generated projects now use
LApp!(APP = App::new().build())for cleaner initialization - Improved template structure: The hello world template now follows current best practices with proper imports and macro usage
Generated projects now compile successfully out of the box without manual fixes.
[4] Built-in constructor implementation in hotaru_meta
Hotaru now includes its own implementation of the constructor pattern (similar to the ctor crate) to ensure projects compile without additional dependencies.
By default, Hotaru uses a built-in constructor implementation that supports Linux, macOS, and Windows. This is production-ready and convenient for most use cases.
If you encounter any issues or want the battle-tested ctor crate instead, you can switch to the external implementation:
[dependencies]
hotaru = { version = "0.7.6", features = ["external-ctor"] }
ctor = "0.4.0" # Required when using external-ctor featureThe built-in implementation is provided for convenience and is production-ready for the supported platforms. However, if you experience any platform-specific issues, switching to the external ctor crate is recommended.