Tracks
/
Cairo
Cairo
/
Exercises
/
Magical Measurements
Magical Measurements

Magical Measurements

Learning Exercise

Introduction

Type conversions in Cairo allow you to transform data from one type to another, enabling flexible and safe data manipulation.

Basics

Cairo provides several mechanisms for type conversion:

Direct Casting

For compatible numeric types, you can use direct casting:

let small_number: u8 = 42;
let big_number: u32 = small_number.into();

The Into Trait

The Into trait enables conversion from one type to another:

let value: u16 = 100;
let converted: u32 = value.into();

The TryInto Trait

For conversions that might fail, use TryInto which returns an Option:

let large_value: u32 = 70000;
let small_value: Option<u16> = large_value.try_into();

match small_value {
    Option::Some(v) => println!("Converted: {}", v),
    Option::None => println!("Conversion failed"),
}

Custom Type Conversions

You can implement Into for your own types:

#[derive(Drop)]
struct Celsius {
    value: i32,
}

#[derive(Drop)]
struct Fahrenheit {
    value: i32,
}

impl CelsiusIntoFahrenheit of Into<Celsius, Fahrenheit> {
    fn into(self: Celsius) -> Fahrenheit {
        Fahrenheit { value: (self.value * 9) / 5 + 32 }
    }
}

Safety Considerations

  • Use TryInto when conversion might fail (e.g., large to small types)
  • Use Into when conversion always succeeds
  • Always handle Option::None cases from TryInto
  • Consider overflow and underflow when converting between signed and unsigned types

Instructions

Astrid, an adventurous alchemist, is trying to standardize the magical units of measurement she collects from different realms. Some realms use signed measurements (which can be negative), while others use unsigned ones (which are always positive). On top of that, Astrid has two custom types for certain rare ingredients, and she needs a way to easily convert between these types.

Your mission is to help Astrid convert between signed and unsigned integers, and create custom type conversions for her special ingredient types using Cairo’s Into and TryInto traits.

1. Converting Magical Units Between Signed and Unsigned

Astrid has measurements that sometimes come in positive or negative values (signed integers), but for certain tasks, she needs to ensure the values are always positive (unsigned integers).

Help Astrid by writing a function that converts:

  1. A signed integer (i32) to an unsigned integer (u16).
  2. An unsigned integer (u16) to a signed integer (i32).
let signed_value: i32 = -42;
match convert_signed_to_unsigned(signed_value) {
    Option::Some(v) => println!("Converted to unsigned: {}", v),
    Option::None => println!("Failed to convert: {}", signed_value),
} // prints "Failed to convert: -42"

let unsigned_value: u16 = 42;
let signed_value: i32 = convert_unsigned_to_signed(unsigned_value);
println!("Converted to signed: {}", signed_value); // prints "Converted to signed: 42"

2. Custom Ingredient Types Conversion

Astrid works with two rare ingredients, Essence and Elixir, which are represented by custom types. She wants to be able to convert Essence to Elixir, but not the other way around.

Help Astrid by creating two custom types, Essence and Elixir, and implementing the Into trait to convert from Essence to Elixir.

Write a function that accepts an Essence and converts it into an Elixir using .into().

#[derive(Drop)]
struct Essence {
    potency: u16,
}

#[derive(Drop)]
struct Elixir {
    strength: u16,
}

fn convert_essence_to_elixir(essence: Essence) -> Elixir {
    // Convert the Essence to Elixir using the Into trait.
    essence.into()
}

fn main() {
    let essence = Essence { potency: 100 };
    let elixir: Elixir = convert_essence_to_elixir(essence);
    println!("Elixir strength: {}", elixir.strength); // Elixir strength: 100
}
Edit via GitHub The link opens in a new window or tab
Cairo Exercism

Ready to start Magical Measurements?

Sign up to Exercism to learn and master Cairo with 25 concepts68 exercises, and real human mentoring, all for free.