Skip to main content

Track

Struct Track 

Source
pub struct Track {
    pub span: Span,
    pub slot: u16,
    pub tick: u16,
    pub unit: Unit,
}
Expand description

A time axis: things placed by when they happen, rather than flowed.

§Why this is a primitive

This crate refused to name it until 2026-08-15, on the argument that a description expressive enough to draw a timeline is a component library wearing a description’s name. The refusal is withdrawn, and it is worth being precise about what was wrong with it, because the reasoning it used applies to real cases and should not be discarded with it.

What a timeline needs that a List does not is one thing: placement. Where a thing sits is a fact about the thing, the way a row’s primary text is, and it is not derivable from order. Everything else a day view draws – the labels, the gridlines, the item bodies, the tones – is furniture this vocabulary already names. Measured against goingson’s day-planning-render.js, the only members it needed and could not get were at and minutes.

So the timeline was never a component library’s worth of vocabulary. It was two integers, and the refusal was priced as though it were the whole widget. The test that matters is not “does this shape look complicated” but “how many members does it actually add, and are they facts or presentation”. Slot heights, gridline colour, how overlaps stack and which hour scrolls into view on open are all presentation and all stay the renderer’s, which is why they are absent here.

§What it does not carry

No pixel measure, no scroll offset, no drag affordance. A renderer draws the span at whatever density its host uses; makeover-geometry owns that the way it owns everything else measured in pixels.

Fields§

§span: Span

The window the axis covers.

§slot: u16

The granularity a thing can be placed on, in minutes.

goingson’s day view is 15, giving 96 slots across a day. A renderer uses it to decide where gridlines fall and what a drop lands on; it does not constrain Placement, because data arriving from a calendar does not respect anyone’s grid.

§tick: u16

How often the axis labels itself, in its own unit.

60 gives an hourly ruler over a 15-minute grid, which is the common shape and the reason this is separate from slot. Zero means an unlabelled axis.

§unit: Unit

What span, slot, tick and every Placement on it count.

The one field here a renderer cannot derive, and the reason it exists: fraction is unit-agnostic, so a day-granularity track produced correct geometry under an hours-and-minutes ruler until this was added. Geometry never needed it; a label always did.

Implementations§

Source§

impl Track

Source

pub const DAY: Self

An ordinary day: midnight to midnight, quarter-hour slots, hourly ticks.

Source

pub const fn over(span: Span) -> Self

A track over span, with the day’s usual granularity.

Source

pub const fn days(span: Span) -> Self

A strip of whole days: one slot a day, a label a week.

The shape a stretch of leave or a sprint is drawn on. Not a calendar – it does not wrap into weeks, and the crate header says why that distinction is the whole of what a month grid still has over this.

Source

pub const fn slots(self) -> u16

How many slots the axis holds.

Rounded up, so a span that does not divide evenly by slot still has a slot covering its tail rather than dropping it. Never zero: slot of 0 reads as one slot spanning the whole axis rather than a division by zero, since a renderer asking this question has already committed to drawing something.

Source

pub fn fraction(self, minute: u16) -> f32

Where a placement sits on the axis, as a fraction from 0.0 to 1.0.

The one calculation every renderer would otherwise write itself, and the place the three would drift apart. Clamped, so a placement outside the span draws at the edge rather than off it – an event running past midnight is a real thing and truncating it is better than either panicking or drawing it somewhere impossible.

Trait Implementations§

Source§

impl Clone for Track

Source§

fn clone(&self) -> Track

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Track

Source§

impl Debug for Track

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Track

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for Track

Source§

impl Hash for Track

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Track

Source§

fn eq(&self, other: &Track) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Track

Auto Trait Implementations§

§

impl Freeze for Track

§

impl RefUnwindSafe for Track

§

impl Send for Track

§

impl Sync for Track

§

impl Unpin for Track

§

impl UnsafeUnpin for Track

§

impl UnwindSafe for Track

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.