| Crates.io | fromage |
| lib.rs | fromage |
| version | 0.1.1 |
| created_at | 2025-04-04 13:05:53.834885+00 |
| updated_at | 2025-04-06 10:40:33.24019+00 |
| description | A cheesy Rust hack for converting between non-local types |
| homepage | |
| repository | https://github.com/fujiapple852/fromage |
| max_upload_size | |
| id | 1619984 |
| size | 23,317 |
A cheesy Rust hack for converting between non-local types.
TL;DR: Allows implementing From and TryFrom like traits for non-local types without violating
the orphan rules.
This crate has no dependencies or macros, is no_std and forbids unsafe code.
Convert between the two non-local types String and usize:
use fromage::{Fromage, TryFromage};
struct X;
impl Fromage<String, X> for usize {
fn fromage(value: String) -> Self {
value.len()
}
}
impl TryFromage<String, X> for usize {
type Error = ();
fn try_fromage(value: String) -> Result<Self, Self::Error> {
Ok(value.len())
}
}
#[test]
fn test() {
assert_eq!(5_usize, usize::fromage(String::from("hello")));
assert_eq!(5_usize, usize::try_fromage(String::from("world")).unwrap());
}
Experimental.
The orphan rules state that:
> Given impl<P1..=Pn> Trait<T1..=Tn> for T0, an impl is valid only if at least one of the following is true:
>
> - `Trait` is a local trait
> - All of:
> - At least one of the types T0..=Tn must be a local type. Let Ti be the first such type.
> - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
Fromage defines the Fromage and TryFromage traits that mirror the traits in the standard library, except that they
require an impl defined additional type parameter X and therefore fulfil the "At least one of the types T0..=Tn
must be a local type" clause above.
The type parameter X is not used in the trait methods. It may be
any type provided it is both local
and uncovered, typically
a unit struct. It
may be reused for all Fromage and TryFromage implementations within a crate.
The Fromage and TryFromage traits define methods named fromage and try_fromage respectively to avoid conflicting
with the standard library's From and TryFrom traits.
The Fromage and TryFromage traits defined in this crate are distinct from the standard library's From and
TryFrom traits and are not interchangeable. Therefore, if a crate uses the standard library's From and TryFrom
traits in its public API, you cannot use the Fromage and TryFromage traits to implement conversions for the
types required by that crate.
For example, if a crate exposes the following public API then you cannot use an impl Fromage<Foo> for Bar to
implement the conversion.
pub fn foo(value: impl Into<Bar>) { ... }
Typically, a
local newtype
is used to implement the standard library's From and TryFrom traits when both types are non-local.
Either:
struct FooWrapper(Foo);
impl From<FooWrapper> for Bar {
fn from(_value: FooWrapper) -> Self {
Bar
}
}
Or:
struct BarWrapper(Bar);
impl From<Foo> for BarWrapper {
fn from(_value: Foo) -> Self {
BarWrapper(Bar)
}
}
Simple conversions functions can be used instead of the From and TryFrom traits.
fn convert(_value: Foo) -> Bar {
Bar
}
fn try_convert(_value: Foo) -> Result<Bar, ()> {
Ok(Bar)
}
For completeness, the orphan rules allow implementing local MyFrom and MyTryFrom traits which may then be used with
non-local types.
This approach is not recommended as it requires a significant amount of boilerplate code whilst sharing the same limitations as the Fromage approach.
Fromage is distributed under the terms of the Apache License (Version 2.0).
See LICENSE for details.
Copyright 2025