Skip to main content

Material

Enum Material 

Source
pub enum Material {
Show 16 variants Solid([f32; 4]), VertexGradient, LinearGradient { axis: [f32; 2], to_local: ToLocal, stops: Vec<Stop>, ramp: Option<u32>, tile: TileMode, }, RadialGradient { to_local: ToLocal, stops: Vec<Stop>, ramp: Option<u32>, tile: TileMode, }, SweepGradient { to_local: ToLocal, start_angle: f32, end_angle: f32, stops: Vec<Stop>, ramp: Option<u32>, tile: TileMode, }, ConicalGradient { to_local: ToLocal, start_radius: f32, radius_delta: f32, separation: f32, stops: Vec<Stop>, ramp: Option<u32>, tile: TileMode, }, Runtime { program: u32, uniforms: Vec<f32>, textures: [Option<u32>; 4], }, Mesh { slot: u32, alpha: f32, tint: [f32; 4], tile: TileMode, sampling: Sampling, }, Image { to_local: ToLocal, slot: u32, alpha: f32, tile: TileMode, sampling: Sampling, source: [f32; 4], tint: [f32; 4], }, RoundedRect { color: [f32; 4], half_size: [f32; 2], to_local: ToLocal, radius: f32, outer_radius: f32, stroke: f32, }, RoundedRectBlur { color: [f32; 4], to_local: ToLocal, adjust: [f32; 2], r1: f32, exponent: f32, s_inv: f32, min_edge: f32, scale: f32, }, Ellipse { color: [f32; 4], half_size: [f32; 2], to_local: ToLocal, stroke: f32, }, Blur { to_local: ToLocal, slot: u32, step: [f32; 2], sigma: f32, }, Morphology { to_local: ToLocal, slot: u32, step: [f32; 2], radius: f32, dilate: bool, }, Glyph { color: [f32; 4], slot: u32, }, PointField { color: [f32; 4], },
}
Expand description

How a shape is filled.

Variants§

§

Solid([f32; 4])

§

VertexGradient

Color comes from the vertices, and the result is dithered.

Shades as opaque white, so the per-vertex color under Modulate – which is the identity against white – is the whole result. That is the arrangement draw_vertices already uses for a caller’s mesh; what this adds is that it dithers, which Solid must not.

It exists for a gradient the rasterizer interpolates instead of the fragment stage evaluating. A long run of nearly equal values is what bands on an eight-bit target whichever stage produced it, and a route that could not say so would drop the dither silently – which is what §19 of docs/non-parity.md records killing the first attempt at it.

Carries no data: a section’s colors ride on its vertices, and the premultiplied alpha rides with them.

§

LinearGradient

A gradient along an axis, starting at a point in clip space.

Clip space for the start, because the fragment stage locates itself from an interpolated clip position: the alternative, the fragment coordinate builtin, has a different origin in each graphics API and would run the gradient in opposite directions on the two backends.

The axis is in the gradient’s own space, and to_local maps a clip-space offset into it — the same pairing radial and sweep use, and for the same reason. Clip space is anisotropic whenever the target is not square, so projecting onto an axis there weights the two axes by the target’s shape: on a target twice as wide as it is tall, a diagonal gradient runs in the wrong direction.

Fields

§axis: [f32; 2]

End minus start, in the gradient’s own space.

§to_local: ToLocal
§stops: Vec<Stop>
§ramp: Option<u32>

Texture slot holding this gradient’s colors, when they did not fit.

None is the ordinary case: the stops travel in the material and the shader walks them. Some means the recorder tabulated them into an image instead, because there were more than MAX_STOPS, and the shader reads the color at the parameter rather than computing it. The two must agree where both are possible, which is what makes the choice invisible to a caller.

§tile: TileMode

What happens beyond the two endpoints.

The parameter a gradient is sampled by runs from zero at one end to one at the other and is defined everywhere else too, so a shape larger than its gradient asks a question the stops do not answer. Clamping holds the end colors, which is the usual choice; repeating tiles the ramp, which is what a stripe pattern is; decal draws nothing outside, the same meaning it has for an image.

§

RadialGradient

A gradient outward from a center, in clip space, where to_local carries the radius: it maps the clip-space offset so that the gradient’s edge lands at unit distance.

Fields

§to_local: ToLocal
§stops: Vec<Stop>
§ramp: Option<u32>

Texture slot holding this gradient’s colors, when they did not fit.

None is the ordinary case: the stops travel in the material and the shader walks them. Some means the recorder tabulated them into an image instead, because there were more than MAX_STOPS, and the shader reads the color at the parameter rather than computing it. The two must agree where both are possible, which is what makes the choice invisible to a caller.

§tile: TileMode

What happens beyond the radius. See Material::LinearGradient.

§

SweepGradient

A gradient around a center, in clip space, running from start_angle to end_angle in radians.

Fields

§to_local: ToLocal
§start_angle: f32
§end_angle: f32
§stops: Vec<Stop>
§ramp: Option<u32>

Texture slot holding this gradient’s colors, when they did not fit.

None is the ordinary case: the stops travel in the material and the shader walks them. Some means the recorder tabulated them into an image instead, because there were more than MAX_STOPS, and the shader reads the color at the parameter rather than computing it. The two must agree where both are possible, which is what makes the choice invisible to a caller.

§tile: TileMode

What happens outside the swept arc.

Unlike the other two this can be a no-op: a sweep covering the whole turn has no outside, and every direction lands within it.

§

ConicalGradient

A gradient between two circles, the general form the other two are special cases of.

center is the first circle’s center in clip space, and to_local maps a clip-space offset into a space where that center is the origin and the second circle’s center lies at (separation, 0). Putting the separation on an axis costs nothing – the rotation folds into a matrix that has to be there anyway – and buys the second center for one float instead of two, which is what makes this fit at all.

The radii are in that same space and are not normalized, unlike the radial gradient’s, because there are two of them and a scale can only remove one. Carrying both plainly also means the degenerate cases need no special handling: concentric circles are separation == 0, and a cone rather than a tube is radius_delta != 0.

Fields

§to_local: ToLocal
§start_radius: f32

Radius of the first circle.

§radius_delta: f32

Second radius minus the first.

§separation: f32

Distance between the two centers.

§stops: Vec<Stop>
§ramp: Option<u32>

Texture slot holding this gradient’s colors, when they did not fit. See Material::LinearGradient.

§tile: TileMode

What happens where the parameter leaves the unit interval. See Material::LinearGradient.

§

Runtime

A caller’s own fragment program, with the floats it reads.

The program is named rather than carried: registering one builds a pipeline, which is expensive and outlives any draw, so a context holds them and a material names which. The floats travel in the same uniform block every other material uses, which is what lets an effect exist without a second descriptor set.

Fields

§program: u32
§uniforms: Vec<f32>
§textures: [Option<u32>; 4]

The textures the program may sample, in the order it declares them.

None in a position means the program does not read that binding, and the backend binds its placeholder there – a pipeline must have every binding it declares bound, however unreachable the branch reading it.

The count is fixed rather than free because the descriptor set layout every pipeline is built against has to be one layout. Four is what that costs: three unused image bindings on a draw that samples nothing, against a second set and a second layout for the draws that want more than one.

§

Mesh

A texture, sampled at coordinates the vertices carry.

Deliberately not Material::Image with a switch on where its coordinates come from. An image mapped from clip space needs an origin, a matrix and a source rectangle to say which part of a sheet it draws; a mesh needs none of them, because a caller stating a coordinate per vertex has already answered all three. What is left is small enough to be its own thing, and keeping it separate means neither carries a field that means nothing for it.

This is what makes a sprite batch one draw: a hundred quads reading a hundred different parts of one sheet differ only in their vertices.

Fields

§slot: u32

Index into the texture table given at submission.

§alpha: f32

Scales the sampled color, applied to premultiplied color like Material::Image’s.

§tint: [f32; 4]

Straight color the sampled texel is multiplied by; white changes nothing.

§tile: TileMode

What happens where a vertex names a coordinate outside the texture.

§sampling: Sampling

How to read between texels.

§

Image

A texture, sampled through a mapping from clip space.

origin and to_local together are an affine: a clip-space position maps to texture coordinates as to_local * (clip - origin), which lands the image’s top-left corner at zero and its bottom-right at one. The same pair a radial gradient uses, for the same reason — clip space is anisotropic on a non-square target, so a mapping that ignored it would stretch every image by the aspect ratio.

Which texture is not named here. The material is data the recorder produces without touching the device, so it carries a slot into the table supplied at submission instead of a backend handle.

Fields

§to_local: ToLocal
§slot: u32

Index into the texture table given at submission.

§alpha: f32

Scales the sampled color, for drawing an image translucently.

Applied to premultiplied color, so it scales the whole texel rather than only its alpha. A texture holds premultiplied color whether it was uploaded or rendered into, and treating a sample as straight alpha would apply the alpha twice — invisible for an opaque image, and plain the moment one translucent image is drawn into another.

§sampling: Sampling

How to read between texels.

§source: [f32; 4]

The part of the texture to draw, as [u0, v0, u1, v1] from zero to one.

The whole texture is [0, 0, 1, 1], which is what every caller wanted until sprite sheets. Normalized rather than in texels because a material is built by a recorder that has never seen the texture and cannot know how large it is; the caller who uploaded it does.

Applied after tiling rather than before, so a repeat repeats the selected piece rather than the whole sheet – which is the only reading of “tile this sprite” that means anything.

§tint: [f32; 4]

Straight color the sampled texel is multiplied by; white changes nothing.

What turns one monochrome icon sheet into every state a control has. A generalization of alpha rather than a rival to it: a tint of [1, 1, 1, a] is exactly that scaling, and both are applied because removing the narrower one would break callers for no gain.

Straight rather than premultiplied because that is how a caller states a color, and the shader premultiplies it before multiplying a texel that already is – scaling color by the tint’s alpha as well, which is what keeps the result premultiplied rather than merely close to it.

§

RoundedRect

A rounded rectangle evaluated per fragment rather than tessellated.

The shape an interface is mostly made of, and the one where computing coverage beats building triangles for it. A tessellated rounded rectangle costs vertices proportional to how round it is and has hard edges unless the whole pass is multisampled; this is two triangles whatever the radius, and antialiases itself from the distance field it already computes.

The geometry is in the shape’s own space, with to_local mapping a clip-space position into it – the same pairing the gradients use, and for the same reason: clip space is anisotropic on a target that is not square, and a distance measured there would round the corners by different amounts on each axis.

Fields

§color: [f32; 4]
§half_size: [f32; 2]

Half the width and height, in the shape’s own space.

§to_local: ToLocal
§radius: f32

Corner radius, in the shape’s own space.

§outer_radius: f32

The radius the outline’s outer edge turns through, which is not always the radius grown by half the stroke.

An outline is the difference of two offset shapes rather than a band around one, and the outer offset is where a join shows. Grow a rounded corner and you get a bigger rounded corner, so this is radius + stroke / 2 for anything with a radius, and for anything with a round join. A mitered square corner is the exception: its offset is still square, so this is zero and the field draws the point the join asks for.

Carried rather than derived because the shader cannot see the join, and because deriving it wrongly is what made a square-cornered stroke come out with rounded corners and be refused this route altogether.

§stroke: f32

Trace the outline at this width rather than filling, in the shape’s own space. Zero fills.

Costs a distance field nothing: the field already says how far every fragment is from the edge, so an outline is the band where that is small. Tessellating one instead means building a second shape – offset inward and outward, with the corners resolved – which is where a stroked outline gets its vertex count and its joins.

§

RoundedRectBlur

A blurred rounded rectangle evaluated per fragment, with no blur pass.

The sibling of Self::RoundedRect, and the reason it is worth having is that the general route costs three passes per shape – one for the content and two for a separable Gaussian – where this costs one draw in the pass already being recorded. On a Raspberry Pi 5 three shadows that way are 7.8 ms of a 26.8 ms frame and nine of its fourteen passes.

The method is Raph Levien’s “Blurred rounded rectangles”, which is what upstream’s SolidRRectBlurContents evaluates too: the exact convolution of a Gaussian with a rounded rectangle has no closed form, and this approximates it as a product of two error functions along an axis, corrected for the corners by measuring distance with an exponent other than two. Every field here is a number the CPU precomputed for that expression rather than anything a caller stated – see Canvas::rrect_blur_material, which is the only place they are derived.

Only where every corner shares one circular radius, which is upstream’s condition too. Anything else takes the general route.

Fields

§color: [f32; 4]
§to_local: ToLocal
§adjust: [f32; 2]

Half the rectangle, less r1, in the shape’s own space.

§r1: f32

The corner radius the approximation uses, which is not the caller’s: it grows with the deviation, because a blurred corner is rounder than a sharp one.

§exponent: f32

The exponent the corner distance is measured with. Two is a circle; this is larger, which is what makes the blurred corner’s profile match a Gaussian’s rather than a circle’s.

§s_inv: f32

One over the deviation, which is what the error function takes.

§min_edge: f32

The shorter side, which bounds how far the fade can reach before the two edges of the shape meet.

§scale: f32

Normalizes the fade so that the middle of a large shape reaches full coverage.

§

Ellipse

An ellipse evaluated per fragment.

Its own variant rather than a rounded rectangle with a large radius, which gives a stadium: past half the shorter side a rounded rectangle stops changing, where an ellipse keeps curving along both axes.

The same geometry a rounded rectangle carries, less the radius, which the two axes already state.

Fields

§color: [f32; 4]
§half_size: [f32; 2]

The two semi-axes, in the shape’s own space.

§to_local: ToLocal
§stroke: f32

Trace the outline at this width rather than filling. Zero fills.

§

Blur

One axis of a separable Gaussian blur of a sampled texture.

Separable because a two-dimensional Gaussian is the product of two one-dimensional ones, so blurring along each axis in turn gives the same result as a square of taps at a fraction of the cost: at a radius of sixteen that is thirty-three taps against a thousand and eighty-nine. Two passes are the price, which is why this names an axis rather than describing the whole blur.

Fields

§to_local: ToLocal
§slot: u32
§step: [f32; 2]

One tap’s step, in the sampled texture’s own coordinates.

The axis and the texel size together: a horizontal pass over a target w wide steps (1/w, 0). Stated here rather than derived in the shader because the shader does not know the size of what it is sampling.

§sigma: f32

Standard deviation, in taps.

The tap count follows from it – the kernel reaches (sigma - 0.5) * sqrt(3) each way, which is upstream’s radius for a given deviation – so a caller sets how soft the result is and nothing else.

§

Morphology

One axis of a morphological filter of a finished layer.

The largest or smallest sample within a radius, per channel, which is what dart:ui calls ImageFilter.dilate and ImageFilter.erode. Like the blur it is separable – a rectangular structuring element is the product of two intervals – so two passes give the square of taps.

Unlike the blur it is also decomposable: dilating by a and then by b is dilating by a + b exactly, because the structuring elements add under the Minkowski sum. A radius past what one pass can reach is therefore split across passes rather than approximated by sampling more sparsely. Sparse taps work for a blur, where a missed sample costs a little smoothness, and do not work here: the result is a maximum, so a missed sample is a scallop in the edge.

Fields

§to_local: ToLocal
§slot: u32
§step: [f32; 2]

One tap’s step, in the sampled texture’s own coordinates. As Self::Blur::step.

§radius: f32

How many texels each way this pass reaches, at most MORPHOLOGY_TAPS.

A whole number of texels, because the structuring element is a set of samples rather than a weighting of them and there is no meaning to half of one.

§dilate: bool

The largest sample in reach rather than the smallest.

§

Glyph

Coverage sampled from an atlas, tinting one color.

Distinct from Self::Image in two ways that matter. The texture is read as coverage rather than as color — one channel scaling a solid, which is what antialiased text is — and the coordinates come from the vertices rather than from a mapping in the paint, so a run of glyphs reading different parts of one atlas is a single draw.

Fields

§color: [f32; 4]

Linear color with straight alpha, as the text is painted.

§slot: u32

Index into the texture table given at submission.

§

PointField

Many discs of one color, evaluated from the vertices rather than the paint, so that a field of them is one draw.

Carries no mapping and no size, which is the whole point of it. Every other fragment-evaluated shape here locates itself through to_local, and to_local holds the shape’s center – so two of them at different places are two materials and cannot share a draw. This one locates itself from the interpolated texture coordinate, which the vertices carry as the unit circle’s corners, so any number of discs at any centers are one material and one draw.

The edge is the same edge. disc_coverage in the shader differentiates the implicit function across the pixel rather than forming a distance, and a derivative of an interpolated value is as available as that of a computed one.

Fields

§color: [f32; 4]

One color for the field, premultiplied as everything here is.

Implementations§

Source§

impl Material

Source

pub fn solid(color: [f32; 4]) -> Self

Source

pub fn sampling(&self) -> Option<Sampling>

How this material reads a texture, if it reads one.

None for a material that samples nothing, which is not the same answer as Sampling::Nearest: one says there is no texture and the other says there is and it is read at a texel’s center.

Here because a caller above the HAL may need to know whether a draw interpolates between texels, and only this type knows. The test harness asks it to size a cross-device tolerance: a filter that forms a weighted sum of texels does so with weights of implementation-defined precision, so two devices disagree on every interpolated pixel by more than the last bit of one store. Deriving that from a recording rather than from the scene that produced it is the point – the scene model has four separate places a sampled texture can come from and a comment recording four occasions on which enumerating them missed one.

Source

pub fn reads_at_computed_offsets(&self) -> bool

Whether this material reads between texels rather than at one.

Every mode but Sampling::Nearest forms a weighted sum: linear over four texels, bicubic over sixteen, mipmapped over two levels of the first. Measured on a Raspberry Pi 5, one scene rendered twice differing only in this: nearest is byte for byte identical between v3d and llvmpipe over the whole frame, and linear reaches a delta of three across seventy per cent of it. Whether this material reads its texture at offsets it computes, rather than at the coordinate it was handed.

True for the two filters that walk a neighborhood: a blur steps out by a sigma, a morphology by a radius, and neither need land on a texel center whatever size the texture is. So this is the one case where a material can say that a read interpolates without knowing the texture – which is why it is a separate question from Self::sampling, and why a layer dilated by a morphology is one of the scenes that put two devices three levels apart.

Source

pub fn with_opacity(self, factor: f32) -> Self

The same material at factor of its opacity.

Applied to every color a material carries, since a gradient’s stops may differ in alpha and scaling them together is what keeps the ramp the same ramp. Straight alpha, so this happens before the premultiply the packing does rather than after it.

Two variants are left alone and it is worth saying which. A blur or a morphology is a filter over a finished pass rather than a paint, so there is no color in it to dim – and nothing asks this of one. A caller’s program is the other: its output is whatever it computes, and this renderer has no uniform it may write to. That is a real limit wherever the caller wanted the dimming, and it is stated at the one place that asks for it.

Source

pub fn is_invisible(&self) -> bool

Whether drawing with this would change anything.

Source

pub fn texture_slots(&self) -> [Option<u32>; 4]

The texture slot this samples, for a backend building its bindings.

Matched exhaustively rather than with a catch-all. A variant that samples something and is not listed here reports no slot, so the backend binds its placeholder and the draw comes out flat white – a plausible picture rather than an error, and one nothing else would explain. Every texture slot this material samples, in binding order.

One entry for everything but a runtime program, which may declare several. A backend building descriptors needs the whole tuple, since a set holds all of them at once; a backend asking only which slot to bind first has Self::texture_slot.

Source

pub fn texture_slot(&self) -> Option<u32>

Source

pub fn is_opaque(&self) -> bool

Pack into the layout the shader declares.

Every member is a four-component vector, which is what lets this be a flat array of floats copied straight into a uniform buffer: the std140 rules the shader’s block is declared with place a vec4 and an array of them at exactly these offsets, so no member needs padding written around it.

Stops beyond the limit are dropped rather than resampled, and the count travels alongside so the shader ignores unused entries instead of blending toward whatever happens to be in them. Whether every pixel this material writes comes out fully opaque.

Used to decide whether a draw may be split into several, which is only safe when writing a pixel twice gives what writing it once does. Under SrcOver that holds exactly when the source is opaque.

False unless shown otherwise. A solid fill carries its alpha and a gradient’s stops carry theirs. Everything else – images, the analytic shapes, blurs, a caller’s own program – is refused outright.

A tabulated gradient still answers from its stops, and that is worth saying because the first version of this refused one. ramp being Some means the shader reads a texture instead of walking the list, not that the list is gone: the recorder maps every stop into the material either way and bakes the ramp from the same list, by interpolating between them. Interpolating between opaque colors gives an opaque one, so the texels are opaque exactly when the stops are. Refusing a ramp cost the whole of occlusion culling’s benefit on the bench’s frame, whose wash is five stops against a MAX_STOPS of four.

Source

pub fn needs_screen_derivatives(&self) -> bool

Whether this material’s shading reads screen-space derivatives.

dpdx and dpdy are computed across a two-by-two quad of fragments, using helper invocations outside the primitive. Whether a scissor keeps those helpers alive is not something either specification settles, and implementations differ: Mesa 26.2.3 keeps them and 25.2.8 does not. So a draw whose shading depends on them gives a different answer at a scissor’s edge than away from it, and splitting such a draw by scissor changes the picture along the seam.

Measured rather than reasoned about: an analytic shadow drawn once reads 217 where the same shadow drawn in four scissored strips reads 206, at the pixel on the strip boundary, on Mesa 25.2.8. See a_scissor_does_not_change_what_a_draw_paints.

True unless shown otherwise, which is the only safe direction: a material wrongly called derivative-free leaves a seam in the frame. The two groups that are shown otherwise are solid fills, whose coverage comes from the rasterizer, and the gradients, which sample their ramp at an explicit level of zero. The rest either take a coverage from the gradient of a distance field – the rounded rectangle, the ellipse and the rounded-rectangle blur – or a texture level from the rate their coordinates change, which is every image fill, or are a caller’s own program.

Source

pub fn dithers(&self) -> bool

Whether this material asks the target for a long run of nearly equal values, and so wants a dither.

The gradients, and nothing else – the same set the shader used to test for itself. Asked here because the shader cannot be the place that knows: it tests the material kind, so a route that draws a gradient under a different kind silently stops dithering. §19 of docs/non-parity.md records that happening, in the reverted attempt at upstream’s vertex-interpolated fast gradient.

False unless shown otherwise. Dithering something with no band to break adds noise to a flat color.

Source

pub fn to_uniform(&self) -> [f32; 64]

Source

pub fn program(&self) -> Option<u32>

The caller’s program this draws with, where it uses one.

None is every material the built-in shader draws, which is all of them but one.

Source

pub fn variant(&self) -> MaterialVariant

Which shader variant this needs, for keying a pipeline.

Every variant lives in one program today, selected by a uniform, so this exists for the moment a material needs its own pipeline rather than pretending that moment has arrived.

Trait Implementations§

Source§

impl Clone for Material

Source§

fn clone(&self) -> Self

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 Material

Source§

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

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

impl PartialEq for Material

Source§

fn eq(&self, other: &Self) -> 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 Material

Auto Trait Implementations§

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.