On this page
- The patterns
- kevy-embedded
- kevy-client and kevy-client-async
- kevy-config
- kevy-store
- kevy-index
- kevy-text, kevy-vector, kevy-sql, kevy-window
- kevy-persist and kevy-replicate
- kevy-rt
- kevy-resp, kevy-resp-client, kevy-verbs
- kevy and kevy-cli
- Cluster and election crates
- Storage building blocks
- System and utility crates
Rust API changes in 7.0
7.0 brings every public Rust API of the workspace in line with the Rust API Guidelines. This page lists every change a caller can see, crate by crate, as old → new. A program that talks to kevy over the wire needs none of it; the upgrade guide covers what else 7.0 changes.
The patterns
Most of the changes are one of six shapes, applied everywhere they fit:
- A
boolparameter is an enum named for its meaning.store.copy(a, b, true)isstore.copy(a, b, CopyMode::Replace). Where two flags could combine illegally, one enum takes both (set(k, v, e, nx, xx)→SetCondition::{Always, IfAbsent, IfPresent}). A setter named for its flag, with the flag as its only argument, keeps itsbool. - Structs and enums the library may grow are
#[non_exhaustive]. A struct you build takesDefaultand assignment or itswith_*builders, ornew(…)where a field has no sensible default:
``rust // 6.4 let p = HnswParams { m: 16, ef_construction: 200, distance: Distance::Cosine }; // 7.0 let p = HnswParams::default().with_m(16).with_ef_construction(200) .with_distance(Distance::Cosine); ``
A match on an enum from another crate needs a _ arm.
- A type with invariants keeps its fields private and exposes them as methods of the same name without a
get_prefix (civil.y→civil.year()). - A free function that took a type first is a method on it (
epoch_from_civil(c)→c.to_epoch(),parse_url(u)→ParsedUrl::parse(u)). - An error is a type, not a
String. Each implementsDisplayandstd::error::Error, isSend + Sync, and where the text reached the wire,as_wire()orto_wire()gives the same text as 6.4. - Traits not meant for outside implementation are sealed. The ones that stay open —
kevy_rt::Commands,kevy_client_async::AsyncTransport,kevy_resp::ArgvView— document what an implementation must uphold.
Every public type now implements Debug (key material is never printed), and every public item carries a running example in its documentation.
kevy-embedded
copy(src, dst, bool)→copy(src, dst, CopyMode):IfAbsent(default) orReplace.hrandfield(key, n, with_values)→hrandfield(key, n)andhrandfield_with_values(key, n).linsert(key, before, pivot, value)→linsert(key, InsertPosition, pivot, value):BeforeorAfter.view_create(name, tree, order_by, desc, mode)→view_create(name, tree, order_by, SortOrder, mode).idx_create_text(name, prefix, fields, positions: bool, values)→TokenPositions::{Omit (default), Record}in that place.Config::with_replay_resync(bool)and the fieldreplay_resync→with_replay_mode(ReplayMode)andreplay_mode(StrictorResync).ScalarQueryOptsandMatchOpts:sortis(field, SortOrder); both are#[non_exhaustive]withwith_filters,with_sort,with_distinct,with_facets,with_offset, … builders.- The change feed takes and returns a
FeedPosition { generation, offset }where it used two integers:changes_tail() -> FeedPosition,changes_since(FeedPosition, limit, prefixes),ChangeBatch::next,FeedError::Resync { tail: FeedPosition }.FeedErrorimplementsDisplayandError. PubsubFrame→PubsubEvent(the subscriber count isi64).TierBudgetSpeciskevy_config::TierBudgetSpec; thetierfeature pulls in kevy-config.LinkKeys::new(local).with_peers(peers).keys_iter(pattern)returnsKeysIter, which walks the keyspace a page at a time, instead ofstd::vec::IntoIterover a copy of every key.scan(cursor, pattern, count)has the server's contract: the cursor names a shard and a position in it,countis how much a page walks (a page may hold more), and a key written during the walk may come back twice. 6.4 copied every key on each call and sliced the copy.idx_drop,view_dropandtable_dropreturnKevyResult<bool>. Every catalog method (idx_create*,view_create,table_declare,table_ensure,table_replaceand the drops) is refused on a replica withKevyError::ReadOnlyand aftershutdownwithKevyError::Closed, like every write.AtomicAllShards::idx_query/idx_countsee the transaction's own writes (6.4 saw the last commit); a failed transaction's writes leave the index with its rollback.- New:
Change::new(offset, argv),ChangeBatch::new(changes, next), and re-exports ofSortOrder,InsertPosition,ReplayMode,FeedPosition,CopyMode,TokenPositions,PubsubEvent. #[non_exhaustive]:Config,TtlReaperMode,ValueFilter,KevyInfo,KevyTierInfo,IdxAdvice,ScalarPage,MatchPage,ReconcileReport,SnapshotEntry,Change,ChangeBatch,PrefixInfo.
use kevy_embedded::{CopyMode, FeedPosition, InsertPosition, ScalarQueryOpts, SortOrder};
store.copy(b"src", b"dst", CopyMode::Replace)?;
store.linsert(b"l", InsertPosition::Before, b"c", b"b")?;
let opts = ScalarQueryOpts::default().with_sort(b"price", SortOrder::Desc);
let from: FeedPosition = store.changes_tail()?;
let batch = store.changes_since(from, 100, &[])?;kevy-client and kevy-client-async
- kevy-client's
FeedFrame { offset, argv }→Change(the same type askevy_embedded::Change);FeedBatch { generation, next_offset, frames }→ChangeBatch { next: FeedPosition, changes }. feed_tail(shard) -> FeedPosition;feed_read(shard, from: FeedPosition, count, prefixes).#[non_exhaustive]:Connection,IdxType,IdxInfo,IdxPage,IdxRow.- kevy-client-async:
AsyncConnection::from_transport<T: AsyncTransport>(T);Pipeline::run<T>(&mut AsyncConnection<T>). - kevy-cluster-rw:
request_read(args, bool)→request_read(args, ReadConsistency):Eventual(default) orPrimary.
kevy-config
- Every section struct,
ConfigandCliOverridesare#[non_exhaustive]: start fromDefaultand assign.PeerEntry::new(id, host, port).with_client_port(..).with_repl_port_base(..)andScopeEntry::new(prefix, writer).with_fallback(..)have no default. NotificationFlagsis a bitset:KEYSPACE | KEYEVENT | …,contains.is_empty()now means no bit is set; 6.4's meaning ("nothing will be published") is!is_active().parse_notification_flags(s)→s.parse::<NotificationFlags>().parse_size,key_from_hex,TierBudgetSpec::parse,PeerEntry::parse_listandScopeEntry::parse_listreturnValueErrorwhere they returned aString;parse_list's text is nowbad peer token: "x".LogOutput::as_str→to_config_str;TierBudgetSpec::as_config_string→to_config_string.EvictionPolicyiskevy_store::EvictionPolicy;AppendFsynciskevy_persist::Fsync.AuditSection,FeedSectionandMetricsSectionare exported at the crate root. Enums andConfigErrorare#[non_exhaustive].- The new fields for encrypted links and the proxy-friendly cluster are in the upgrade guide.
kevy-store
Flags that were bools:
| 6.4 | 7.0 |
|---|---|
set(k, v, e, nx, xx), set_slice(…) | SetCondition::{Always, IfAbsent, IfPresent} |
lmove(s, d, from_left, to_left) | ListEnd for each end |
linsert(k, before, p, v) | InsertPosition::{Before, After} |
rename(s, d, nx) | rename(s, d) and rename_nx(s, d) |
hrandfield(k, n, false) / (k, n, true) | hrandfield(k, n) / hrandfield_with_values(k, n) |
set_notify_capture(n, x, e) | set_notify_capture(impl IntoIterator<Item = KeyspaceEvent>) |
xadd(…, nomkstream, now), xgroup_create(…, mkstream) | MissingStream::{Create, Refuse} |
xreadgroup(…, noack) | AckMode::{Pending, NoAck} |
xautoclaim(…, justid) | ClaimMode::{Deliver, JustId} |
parse_explicit_id(s, end) | parse_explicit_id(s) |
Types:
XClaimOpts::default().with_min_idle_ms(),with_idle_ms,with_time_ms,with_retrycount,with_force,with_mode(ClaimMode)(the fieldjustidismode).ZaddFlags::new(SetCondition, ScoreCompare::{Any, Greater, Less})returnsOption(Nonefor an illegal combination) and takeswith_ch; read it withcondition(),compare(),ch().valid()is gone.StreamId::new(ms, seq),LoadedGroup::new(..),ScoreBound::inclusive(v)/exclusive(v),Score::new(x)/.value().ConsumerGroup's fields are methods:last_delivered_id(),pending_entry(id),pending_range(r),consumer(name),consumers().ConsumerState:name(),pending_count(),last_seen_ms().SealedRows:seq(),file().- Renamed:
iter_entries/groups_iter→entries()/groups();SegListData::iter_range→range();SmallSetData::iter_slicesis gone;bitop_combine(op, s, n)→op.combine(s, n);apply_segmented(store, dir, f)→store.apply_segmented(dir, f). - Errors: the segment row functions return
SegRowsError;StoreErrorandStreamIdErrorimplementDisplayandError;StoreError::as_wire()gives the reply text.KevyError::ReadOnlydisplayswrite refused: this is a read-only replica;KevyError::Store(e)displays the store error's text and returns it fromsource(). - New:
Store::set_row_watch(RowWatch),take_row_changes,has_row_changes,row_watch, withRowWatch,RowChanges,RowChange: the store records, for keys under a watched prefix, the watched fields as they were before the first write since the last take — what an index needs to drop a row's old entry, whichever path wrote the row. - New:
KeyspaceEvent::name(),HExpireCond::keyword(),ZAggregate::keyword(),EvictionPolicy::as_str()/parse(). - Streams: a delivery count is a
u64(PelEntry::delivery_count, the count inLoadedPelEntry,XClaimOpts::with_retrycount).xreadgroupreturns aGroupBatch, whose fields areNonefor an entry a history read hands back after it was deleted. New:XClaimOpts::with_last_id;Store::xtrim(key, TrimTo, TrimMode)withTrimTo::{MaxLen, MinId},TrimMode::{Exact, Approximate}andAPPROX_TRIM_LIMIT;StreamData::trim,node_count,radix_tree_nodes;xgroup_set_delivery_countandxgroup_restore_pending, which a loader uses;StoreError::StreamExhausted. #[non_exhaustive]:KevyError,StoreError,StreamIdError,BitOp,HExpireCond,KeyspaceEvent,XAddIdSpec,GroupCreateMode,ReadGroupId,EvictionPolicy,ZAggregate,SetCondition,ScoreCompare,ExpireStats,TierStats,ColdRead,AutoclaimResult, thePending*replies,PelEntry,ZaddReport.
kevy-index
IndexSpec { .. }andIndexSpec::single_field(..)→IndexSpec::builder(name, prefix, kind, ty).with_field(f)and optionally.with_fields,.with_max_bytes,.with_ann,.with_group_by,.with_positions,.with_values,.with_composite, then.build()?(errorSpecError). The fields are methods of the same name;with_positionsreads ashas_positions(). The field checks moved fromCatalog::createtobuild().Catalog::coerce→IndexValue::coerce(spec.ty(), raw).- Builders:
FieldSpec::new(n).with_weight(w),ValueSpec::new(n).with_type(ty),AnnSpec::new(dim).with_distance(d).with_m(m).with_ef(ef),CompositeCol::new(n, ty).with_order(SortOrder),OrderPath::new(name, Vec<(col, SortOrder)>),ViewSpec::new(name, tree, order_by).with_order(..).with_mode(..).with_via(..),ScalarClauses::new(fetch).with_filters(..).with_sort(pos, SortOrder, ty).with_distinct(..).with_facets(..). The fields nameddescareorder: SortOrder. - Constructors:
Leaf::new,TableIndex::new,WindowSpec::new,Cursor::new,ScalarHit::new,AdviseEntry::new,IndexVerify::new,GlobalPath::new,WindowAudit::new.TableSpec,TableVerify,GroupStats,SegmentStats,AggStatsandWhereClausetakeDefaultand assignment. - Sort direction is
SortOrder(re-exported from kevy-text):Segment::scan(after, desc)→scan(after, SortOrder);scalar_sorted_order→sorted_order(a, b, SortOrder);merge_claused(all, sort_desc, grouped, off, lim)→(all, Option<SortOrder>, off, lim);MaterializedSet::new(k, desc)→(k, SortOrder);page(after, limit, desc)→page(after, limit). AggSegment::apply(k, Some((g, v)), false)→AggRow::Member { group, value };(k, None, false)→AggRow::Removed;(k, None, true)→AggRow::Excluded.MaterializedSet::apply(k, member, order)→Membership::Member(order) | NonMember.- Fields that are methods:
order_excluded();UsageCell's fields (plusmin_margin()). - Functions that are methods:
compile_table(&t)→t.compile();apply_auto→t.apply_auto(&e);advice_of→e.advice(&cat);window_for→cat.window_for(n);window_driver→cat.is_window_driver(n);window_text_for→cat.is_windowed_text(s);value_order_bytes(&v)→v.order_bytes();window_value_of→v.window_value(shape);eval_tree→t.eval(seg);key_in_tree→t.contains(k, seg);key_in_tree_vals→t.contains_values(f);parse_split_point(&s, raw)→s.parse_split_point(raw);split_point_text→s.split_point_text(enc);merge_group(&mut a, &b)→a.merge(&b);narrow_advice(spec, i64)→spec.narrow_advice(Option<i64>);splits_from_sample→splits_from_weighted(points, parts). - A
Segmentkeeps no map from key back to entry, so a write names the value the row was indexed under:apply(key, new)→apply(key, old: Option<&IndexValue>, new);apply_with_values(key, new, vals)→(key, old, new, vals);remove(key)→remove(key, old: &IndexValue);verify_entry(key)→contains(&value, key);stored(key, field)→stored(&value, key, field) -> Option<Vec<u8>>;stored_row(key)→stored_row(&value, key) -> Vec<Option<Vec<u8>>>;max_value()returnsOption<IndexValue>. scan(after, order)returns aScancursor instead of a boxed iterator:while let Some((value, key)) = scan.next_entry() { … };iter_below(bound)→scan_below(bound), withScan::stored_row()for the entry'sVALUES.- New:
Segment::for_spec(&IndexSpec)(the segment an index declares, with its key prefix and value shape),repack(),set_key_dir(bool)/key_dir() -> Option<&KeyDir>(key → value, for indexes a view reads by key),IndexSpec::derive_scalar_refs.PlacementTableis gone.each_entryvisits entries in(value, key)order;countis O(log n). - Errors:
CatalogError(to_wire()),ViewError,TableError(to_wire()),WhereError. - New:
IndexValue::encode/decode/render,AggBy::tag,GroupStats::rank_score,ViewMode::name. #[non_exhaustive]:ValType,IndexKind,IndexState,AdviseShape,AggBy,Partitioning,WindowShape,TableEnsure,IndexValue,ViewMode.
kevy-text, kevy-vector, kevy-sql, kevy-window
- kevy-text:
sorted_order(a, b, bool)→sorted_order(a, b, SortOrder);Sort { field, desc, key }→Sort::new(field, key).with_order(SortOrder::Desc);Filter,Distinct,Facet,TextMatch,CorpusStats→::new(…);QueryOptsandSegmentShape→::default().with_*.TextStats,FacetedMatches,FrozenBucket,FwdRecord,ColdEntryare#[non_exhaustive]. - kevy-vector:
HnswParams::default().with_m(..).with_ef_construction(..).with_distance(..);HnswParams,VectorStats,Distanceare#[non_exhaustive].Hnsw::newpanics form < 2(M = 1 gave unbounded levels), and an embeddedidx_create_annrefuses M = 1 (M = 0 still means the default). - kevy-sql:
KevyType→kevy_sql::ValType(the same type askevy_index::ValType);Served::Yes { paths, view, card }/No { reason }→Served::View { paths, argv }/Card { paths, card }/Refused { reason }, withpaths();table_ddlreturnsDeclarationError.SqlError,CardParam,QueryCard,Compilation,Folded,Plan,PlanEntry,Servedare#[non_exhaustive]. - kevy-window:
WindowRt'sspec,shape,idle_ticksare methods;ColdPageQuery { .. }→ColdPageQuery::parse(text, stats, fetch)withwith_filter,with_sort,with_distinct,with_facets; the cold functions returnColdError.ColdHit,ColdPage,ColdPageQueryare#[non_exhaustive].
kevy-persist and kevy-replicate
- kevy-persist:
Aof::open_with_repair(p, f, resync)andopen_after_replay(p, f, resync, settled)takeReplayMode::{Strict, Resync};replay_aof_in_place(p, resync, quiet, f)→(p, ReplayMode, ReplaySummary::{Print, Quiet}, f);replay_aof_quiet(p, resync, f)→(p, ReplayMode, f). Fsync(stillkevy_persist::Fsync) is#[non_exhaustive], hasas_str/parse, and defaults toEverySec.RewritePolicy::default().with_pct(..).with_min_size(..).with_bytes(..).with_interval_secs(..); the default turns every rule off.ShardsMeta::new(n, routing),ShardsMeta::read(p),m.write(p);RewriteStats::default();dump_aofreturnsRewriteStats. Writers takeW: Writeby value (&mut wstill compiles).- Feed positions:
FeedBoot/FeedBoot::load→feed_meta::boot_position(dir, shard) -> io::Result<FeedPosition>;write_feed_meta(dir, shard, FeedPosition);read_snapshot_cursor() -> Option<FeedPosition>;write_snapshot_to_with_cursor(src, sink, Option<FeedPosition>).Routing(defaultKevyHash) andRewritePlanare#[non_exhaustive]. - A snapshot and a rewritten log can carry one frame beside the keyspace:
SnapshotSource::aux_frame(defaultNone),WithAux::new(src, aux),load_snapshot_with_aux.reshard::commit_reshard(dir, prev_n, target, stores, aux, layout)takes the frame the new snapshots carry. - kevy-replicate:
feed::FeedPosition { generation, offset }(#[non_exhaustive],Copy,Default,const fn new) replaces every (generation, offset) pair:FeedSource::tail(),read(at: FeedPosition, max),FeedRead::Resync { tail },HandshakeReq { from, .. },encode_ack,encode_ping,SnapshotMarker::Ping,ReplicaEvent::Ping,primary_at_handshake().fresh_generationis public. connect_with_timeout,connect_atandconnect_secure→ReplicaClient::connect_with(addr, &ConnectOptions::new(id).with_from(pos).with_timeout(t).with_security(sec));connect(addr, id, offset)stays.ReplicaSecurity::new(local, primary_key). Encryption is the default featuresecure; without it there is noReplicaSecurityor security option.handshake::parse_replicate_from(argv)→HandshakeReq::parse(argv);wire::decode_framereturns(DecodedFrame, usize);DecodedFrame::new(offset, argv).ReplicaErrorandWireErrorimplementsource();WireError'sPartialEqcompares whole values.FeedFrame,HandshakeReq,DecodedFrame,ReplicaSlot,source::Frame,HandshakeError,ReplicaEvent,ReplicaError,WireError,SnapshotMarkerare#[non_exhaustive].
kevy-rt
NotifyClass→kevy_resp::NotifyKind;Commands::notify_class() -> Option<NotifyKind>.ScanArgs→Route::Scan(Result<ScanOpts, ScanOptsError>);parse_slowlog_sub→SlowlogSub::parse;Route::ListMove { from: ListEnd, to: ListEnd };ClientKillFilter::parse() -> Option<(Self, KillReply)>.- Builders:
ResolvedCmd::new(route).with_txn_kind(..).with_quit(..).with_write(..).with_block_hint(..).with_wake_idx(..);XGroupCtx::new(group, consumer).with_ack(AckMode);ReplicaAck::new(offset, age_ms);ReplicationSecurity::new(local).with_replica_keys(keys);LiveRuntimeConfigtakesDefaultand assignment. Runtime::with_replication(enabled)andwith_replication_buffer_size(bytes);with_feed(enabled)andwith_feed_buffer_size(bytes);with_replay_resync(bool)→with_replay_mode(ReplayMode).shard_of_key(key, n, bool)→shard_of_key(key, n, Routing).- New
Commandsmethods, with defaults:snapshot_aux,load_snapshot_aux(frame, full_sync),on_restored(record)andxreadgroup_refusal(store, argv), which checks each part of anXREADGROUPsplit across shards before any part reads. #[non_exhaustive]:Route,BlockHint,BlockKind,ClientKillFilter,GeoHits,SlowlogSub,MultiOp,ZCombine,Propagate,ReplicaApply,ExtensionReduced,TxnKind(Copy, defaultOther),ResolvedCmd,LiveRuntimeConfig,ReplicaAck,XGroupCtx,ReplicationSecurity.
kevy-resp, kevy-resp-client, kevy-verbs
- kevy-resp:
fuzz::Lcg(pub u64)→Lcg::new(seed)andstate();ProtocolErrordisplaysmalformed frame: …and implementsError;ArgvIter<'a, V: ?Sized>;ArgvimplementsFromIterator<&[u8]>,Extend<&[u8]>andHash.PubsubEventlives here now, withinto_payload().CmdError,ProtocolError,NotifyKind,Strategy,FuzzOutcome,FuzzResult,Summary,OpSpecare#[non_exhaustive]. - kevy-resp-client:
parse_url(u)→ParsedUrl::parse(u);parse_secure_url(u)→SecureUrl::parse(u);classify_pubsub(r)→PubsubEvent::try_from(r)(re-exported from kevy-resp).ParsedUrlandClientStreamare#[non_exhaustive]. - kevy-verbs:
emit_zrange(res, bool, ..)→Scores::{Omitted, Included};Claim::new(t, d, bool)→aof::Consumer::{Existing, Created}, also inEffect::RecordReadandRecordReads;scan_optsreturnsScanOptsError,geo::store_searchreturnsStoreSearchError(both withas_wire());reply::store_err_msg(e)→e.as_wire().VerbandScanOptsare#[non_exhaustive]. New:Effect::RecordAddandEffect::RecordHistory(an approximate trim and a history read, recorded as what they did),cmd::stream_resp3andcmd::xreadgroup_refusal, and the internal record verbkevy_resp::ops_table::PENDINGthataof::apply_internalapplies.
kevy and kevy-cli
- kevy:
RuntimeState::new(cfg, impl Into<PathBuf>, n) -> Result<_, OwnershipError>(kevy::OwnershipError, same text as before);secure::keygen(impl AsRef<Path>).AfterDrain(nowClone,Copy,Eq,Hash) andverb_meta::VerbMetaare#[non_exhaustive]. - kevy-cli:
doctor::run(c, bool)/run_scoped(c, bool, scope)→OnWarning::{Report, Fail};Scope { .. }→Scope::default().with_indexes(b).with_views(b);run_delete_prefix(c, p, rate, bool)→DeleteMode::{Unlink, DryRun};run_import(c, src, resume, strict)→(c, src, ImportStart::{Fresh, Resume}, OnErrorReply::{Count, Abort});run_diffandrun_inspecttakeimpl Writeby value;backup::pack/unpacktakeimpl AsRef<Path>;run_backup/run_restore→pack(a, b).map(|_| ())/unpack(..).link::Linkis sealed.Source,Health,Shapeand the report structs are#[non_exhaustive]. The bare-word tool functions are gone (upgrade guide §12).
Cluster and election crates
- kevy-elect:
ElectConfig::default().with_hb_interval(..).with_down_after(..).with_election_timeout(..).with_election_backoff(..).with_election_backoff_jitter(..);PeerAddr::new(node_id, host, port);SecureLinks::new(local, peer_keys);Elector::new(id, peers, addr, role, config, jitter)→Elector::new(id, peers, addr, role).with_config(config).with_jitter(jitter);Transport::spawn*no longer takehb_interval(it is read from the elector);encode(&m)→m.encode(),decode(buf)→Message::decode(buf).InboundEventis private;OutboundandElectorSnapshotcannot be built outside the crate;Message,Role,ElectJitter,DecodeErrorare#[non_exhaustive];DecodeErrorimplementsDisplayandError. - kevy-scope:
MigrationError,OwnershipError,Routing,MigrationStateare#[non_exhaustive]; test aRoutingwithmisdirected_target()/is_local_writer().
Storage building blocks
- kevy-seg:
ManifestEntry { .. }→ManifestEntry::new(file, seg_meta).with_meta(meta);Manifest::sweep(&self, dir)→sweep(&self), which sweeps only the manifest's own directory (given another directory, 6.4 deleted segments that were not its own);SegBuilder::create,Seg::openandManifest::opentakeimpl AsRef<Path>.SegMeta,ManifestEntry,SegErrorare#[non_exhaustive]. - kevy-vlog:
VlogRef { .. }→VlogRef::new(file_id, offset, len);VlogFile::raw_fd()→AsRawFd/AsFd;Vlog::opentakesimpl AsRef<Path>.VlogRef,VlogStatsare#[non_exhaustive]. - kevy-alloc:
SpanMeta's fields are methods;Segment's fields →owner(),spans(),foreign_bytes(),foreign_live();segment::take_foreign(seg)→seg.take_foreign();splice_foreignis anunsafemethod.Statsis#[non_exhaustive].EMPTY_SPAN_HYSTERESISis gone: free pages go back to the OS once they have gone unused forPURGE_DELAYreclaim sweeps, instead of every sweep keeping the first four empty spans.Segment::foreign_bytes()andforeign_live()now report the whole owning heap. - kevy-map:
KevyMapandKevySetimplementIntoIterator(IntoIter,SetIntoIter) and compare by contents withPartialEq/Eq. - kevy-ranktree:
range()returnsRange;FromIterator,Extend, andIntoIterator for &RankTree. - kevy-compress:
decode_with(&dict, x),encode_with,encode_high_with→dict.decode(x),dict.encode(x),dict.encode_high(x);Corrupt→DecodeError(implementsError).
System and utility crates
- kevy-sys:
Poller::add/modify(fd, read, write)→(fd, Interest)(READ,WRITE,READ | WRITE,NONE);tcp_listen,tcp_listen_reuseport,unix_listen→Socket::tcp_listen, …;waker()→Waker::new();Socket::from_raw_fdisstd::os::fd::FromRawFd(import the trait);AsRawFdandIntoRawFdare implemented.Eventis#[non_exhaustive]. - kevy-uring:
FileRead { .. }→FileRead::new(fd, offset, len)(#[non_exhaustive]);KernelTimespecisCopy. - kevy-time:
Civil { y, m, d, h, min, s }→Civil::from_date(y, m, d)?.with_time(h, min, s)?; the fields areyear(),month(),day(),hour(),minute(),second();civil_from_epoch(s)→Civil::from_epoch(s);epoch_from_civil(c)→c.to_epoch();checked_epoch_from_civilis gone (the conversion can no longer overflow).CivilimplementsHashandOrd. - kevy-noise:
Erroris#[non_exhaustive];FramesisClone. - kevy-crypto:
AuthErrorimplementsError. - kevy-scalar:
Scalar,ScalarErrorare#[non_exhaustive]. - kevy-lua:
FlushModeis#[non_exhaustive]and defaults toSync. - kevy-lua-host:
CurrentTagis gone;with_current::<T>returnsNonefor the wrong type or for a context already lent out, where 6.4 could hand out a second mutable borrow; theLuaHost<T>bound moved to the impls. - kevy-bench:
report(label, s)→s.report(label);Statsis#[non_exhaustive]. - kevy-tmpdir:
TmpDir::close()returnsio::Result<()>. - The Tauri plugin's
ErrorgainsOther(String).