Skip to main content

Smit

Struct Smit 

Source
pub struct Smit(/* private fields */);
Expand description

A short marker a dog attaches to a sheep for shep flock to paint.

shep stores one and prints it. It does not parse it, has no opinion about what it means, and never will: ▲ main@a1b2c3 is a deploy tool’s sentence, not shep’s, and keeping it that way is what makes this a general mechanism rather than one feature’s field.

§The rule

A smit is non-empty once whitespace is discounted, at most Self::MAX_CHARS characters, and carries no char::is_control character — \u{1b} included, which is_control already covers and which is named separately in this doc anyway, because it is the one an attacker reaches for and a reader should not have to know the classification to see that it is handled.

Refused, never repaired. The text is stored exactly as it arrived: shep does not trim it, strip from it, or otherwise hand back something the publisher did not send. crate::kv’s key grammar and value cap set the same precedent for the same kind of value, and the publisher here is a program, so a refusal it can see and fix beats mangling it cannot.

§Why the cap counts characters

Self::MAX_CHARS is a count of chars, not of bytes and not of display columns. Bytes would refuse a legitimate CJK smit at roughly a third of its apparent length. Display columns are what a table renderer measures, but they depend on the terminal and on a width table this parser has no business carrying. Characters are the honest thing a validator can promise cheaply. 48 is measured against the reference smit ▲ main@a1b2c3 at thirteen: room for a long branch name, without letting one column swallow the table.

§Why validation lives here rather than at the renderer

shep’s own output::width::sanitize_cell deliberately KEEPS a well-formed CSI sequence, because shep’s colouring is made of them, so it is not a guard against a third party’s string. Refusing here means shep flock, shep describe, --format json, the lookout, the MCP tool schema and every bus subscriber are safe by construction instead of six places each remembering.

Debug is derived, and that is the deliberate decision (IR-41): a smit carries no environment and no secret. It is a string a dog asked to have painted in public, so redacting it would hide the thing an operator is debugging.

§Example

use shep_core::protocol::Smit;

assert_eq!("▲ main@a1b2c3".parse::<Smit>()?.as_str(), "▲ main@a1b2c3");
assert!("\u{1b}[2Jgone".parse::<Smit>().is_err()); // no escapes

Implementations§

Source§

impl Smit

Source

pub const MAX_CHARS: usize = 48

The longest a smit may be, in characters. See the type doc for why characters rather than bytes or display columns.

Source

pub fn as_str(&self) -> &str

The marker as text, exactly as its publisher sent it.

Trait Implementations§

Source§

impl Clone for Smit

Source§

fn clone(&self) -> Smit

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 Debug for Smit

Source§

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

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

impl<'de> Deserialize<'de> for Smit

Hand-written rather than derived, and that is the whole security property.

A derived impl would accept anything a String accepts, so a smit carrying \u{1b}[2J would reach the daemon’s memory and every listing built from it. docs/dogs.md tells dog authors to speak this wire directly, so a dog written in another language never runs core::str::FromStr — the daemon has to validate what it decodes, not trust that it was constructed properly.

Source§

fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for Smit

Source§

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

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

impl Eq for Smit

Source§

impl FromStr for Smit

Source§

fn from_str(text: &str) -> Result<Self, Self::Err>

§Errors
Source§

type Err = SmitError

The associated error which can be returned from parsing.
Source§

impl PartialEq for Smit

Source§

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

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

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

Inequality operator !=. Read more
Source§

impl Serialize for Smit

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Smit

Auto Trait Implementations§

§

impl Freeze for Smit

§

impl RefUnwindSafe for Smit

§

impl Send for Smit

§

impl Sync for Smit

§

impl Unpin for Smit

§

impl UnsafeUnpin for Smit

§

impl UnwindSafe for Smit

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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
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> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

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

Source§

type Error = !

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.