Month: March 2025

Generic Types in Rust

Use generics to create definitions for items like function signatures or structs, which we can then use with many different concrete data types.Ā Defined with <T>

Generics make programming easier without reducing runtime performance.

Generics uses process called Monomorphization where compiler replaces generic placeholders with data types.

struct Language<T, T1, T2>{
    name: T,
    stable_version: T1,
    launched_year: T2
}


fn main{
    let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    println!("Programming language is {:?}", pro_langauge_rust)
}

Output-

Programming language is Language { name: "Rust", stable_version: 1.84, launched_year: 2012 }

Gneneric Method

struct Language<T, T1, T2>{
    name: T,
    stable_version: T1,
    launched_year: T2
}
//struct Color(u8,u8,u8);

impl<T,T1,T2> Language<T, T1, T2> {
    fn get_name(&self) -> &T
    {
        &self.name
    }    
} 

fn main {
   let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    println!("Programming language is {:?}", pro_langauge_rust.get_name())
}

Ouput

Programming language is "Rust"

Loading

Traits in Rust

trait defines the functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way. We can use trait bounds to specify that a generic type can be any type that has certain behavior.

Traits are similar to a feature often calledĀ interfacesĀ in other languages, although with some differences.

Struct

Define a struct – in this case Langauge struct with fields and data types

struct Language{
    name: String,
    stable_version: f32,
    launched_year: u32
}

Define Trait and implemenation

Define trait Description with represent method. Implement trait Description for Language struct.

trait Description{
    fn represent(&self) -> String;
}

impl Description for Language{
    fn represent(&self) -> String{
        format!("the language {} was lauched in {} year and current stable version is {}", self.name, self.launched_year, self.stable_version)
    }

}

Main Block

Instantiate Langauge and call the represent method implemented for Struct

{
    let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    println!("Programming language is {}", pro_langauge_rust.represent())
}

Output

Programming language is the language Rust was lauched in 2012 year and current stable version is 1.84

Default Trait

In the previous example Trait just has the definition but no implementation. Define a default implementation to the trait and no remove the implementaion for Langauge

trait Description{
    fn represent(&self) -> String{
        String::from("is the langauge you should learn.")
    }
}

impl Description for Language{ 
// No implementation
}

fn main{

   let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    println!("{} {}", pro_langauge_rust.name,  pro_langauge_rust.represent());
}

Output

Rust is the langauge you should learn.

Loading

Create Vercel project to host XM Cloud Site

Sitecore XM Cloud Vercel connector helps to host Website to Vercel

Before using this connector you have to create Project and Environment.

Prerequisite

Before we ould start configuring Project in Vercel we need following info-

JSS APP Name- can be found and should be same as configured in package.json in sxastarter folder

In this case it is sxastarter

GRAPHQL ENDPOINT

GraphQL endpoint for published Sitecore items i.e. Delivery/Live endpoint is –

https://edge.sitecorecloud.io/api/graphql/v1

Sitecore API Key

This should be the GraphQL Delivery token i.e. GQL token-

There are different ways to generate GQL Token. One of the way is generate from portal. Login to XM Cloud and navigate to Projects ==> Environments ==> Details tab

Click on Generate Delivery API Key (Note this key as this won’t be avilable again and needs to be re-generated again if lost)

Note this API key as this is required later whilst configuring the Vercel hosting.

Publish Site

Publish the site to Edge before starting to configure Project in Vercel, since we are configuring GraphQL Delivery API token items in Sitecore needs to be published

Create a Project in Vercel

Login to Vercel and Create Project-

Since I have logged in using GitHub account it displays the repositories in Github the project will be based on-

Import the repository-

Configure Project

Once the project is created configure the project by selecting the Framework and repo folder FE code exists-

Choose the Nextjs Framework

Choose the sxastarter folder from the repo i.e. /src/sxastarter

Add following environment variables extracted earlier-

JSS_APP_NAME – sxastarter

GRAPH_QL_ENDPOINT – https://edge.sitecorecloud.io/api/graphql/v1

SITECORE_API_KEY – Delivery API Key generated from portal.

Should have this confiogured in the Vercel Project-

Deploy the Project

Deployment complete-

Visit the Site and should get the same view as configued in local environment and Experience Editor-

Thats all for how to create a Vercel Project and deploy site.

Errors-

If you see error-

The field 'item' does not exist on the type 'query'

Resolution-

Publish the site

Loading

Structs in Rust

Struct group multiple items of mixed data types. Elements are named instead of order as defined in tuple.

Defining struct

struct Language{
    name: String,
    stable_version: f32,
    launched_year: i32
}

{ 
    let mut pro_langauge = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    println!("Programming language {} current version is {} and launched on {}", 
    pro_langauge.name, 
    pro_langauge.stable_version, 
    pro_langauge.launched_year);

    pro_langauge.name = String::from("java");
    println!("Programming language is {:?}", pro_langauge);
}

Output

Programming language Rust current version is 1.84 and launched on 2012
Programming language is Language { name: "java", stable_version: 1.84, launched_year: 2012 }

Struct managed in memory

Struct Clone

Struct clone is possible using clone() method. Will take the above example to clone the struct instance.

    let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    let pro_langauge_java = Language{
        name: String::from("Java"),
        ..pro_langauge_rust
    };

    println!("Programming language {} current version is {} and launched on {}", 
    pro_langauge_rust.name, 
    pro_langauge_rust.stable_version, 
    pro_langauge_rust.launched_year);
    
    println!("Programming language is {:?}", pro_langauge_java);

Here some of the fields are copied from the other instance using .. notation and the name for the new instance is different.

Output

Programming language Rust current version is 1.84 and launched on 2012
Programming language is Language { name: "Java", stable_version: 1.84, launched_year: 2012 }

You cannot copy eveything from the previous instance to the new instance as this breaks the rule oif Rust of having a single variable with same data. For this a clone() method is used.

let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };
 let pro_langauge_java = Language{
        ..pro_langauge_rust
    };

Here all the data of the variable pro_langauge_rust is trying to copy to pro_langauge_java gives an error.

Use clone method

let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    let pro_langauge_java = Language{        
        ..pro_langauge_rust.clone()
    };

    println!("Programming language {} current version is {} and launched on {}", 
    pro_langauge_rust.name, 
    pro_langauge_rust.stable_version, 
    pro_langauge_rust.launched_year);
    
    println!("Programming language is {:?}", pro_langauge_java);

Output

Programming language Rust current version is 1.84 and launched on 2012
Programming language is Language { name: "Rust", stable_version: 1.84, launched_year: 2012 }

Struct Methods

Subroutine associated with a struct and the first parameter is a reference to the struct instance. It is declared same as funciton using fn keyword.

In the below example the struct method is implemeted using imp keyword. The method takes the reference to the instance i.e. self. This method is called on the Struct instance in main block.

// Implementation of Struct
impl Language{
    fn get_name(&self) -> &str
    {
        &self.name
    }    
}

fn main() {
    let pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
    };

    let pro_langauge_java = Language{        
        ..pro_langauge_rust.clone()
    };
 
    let language_name = pro_langauge_rust.get_name();
    println!("Language name is {:?}", language_name);
}

Update the Struct instance

To update make the struct instance mutable with mut keyword. Implement the method to update in Struct implementaion.

See the update_version method and how is called from the main block

impl Language{
    fn get_name(&self) -> &str
    {
        &self.name
    }    

    fn update_version(&mut self, version: f32){
        self.stable_version = version;
    }
}

 let mut pro_langauge_rust = Language{
        name: String::from("Rust"),
        stable_version: 1.84,
        launched_year: 2012
};

let language_name = pro_langauge_rust.get_name();
println!("Language name is {:?}", language_name);

pro_langauge_rust.update_version(1.85);
println!("Latest version {:?}", pro_langauge_rust.stable_version);

Output

Language name is "Rust"
Latest version 1.85

Associated Functions/Constructor

Functions associated with a struct data type. They are similar to methods but functions does not have a self input parameter. So we cannot use an associated function to reference the data from whithin a specific instance of a struct.

Mainly associated functions in Struct are used as a constructor to build a new instance of a Struct. See below example a new function with the name parameter and return the instance of Struct. The instance of Struct is created in main block.

impl Language{
    fn get_name(&self) -> &str
    {
        &self.name
    }    

    fn update_version(&mut self, version: f32){
        self.stable_version = version;
    }

    fn new(name: &str) -> Language{
        Language { name: String::from(name), stable_version: 0.0, launched_year: 0000 }
    }
}

{
    let mut pro_langauge_rust = Language::new("Rust");

    let language_name = pro_langauge_rust.get_name();
    println!("Language name is {:?}", language_name);

    pro_langauge_rust.update_version(1.85);
    println!("Latest version {:?}", pro_langauge_rust.stable_version);
}

Output

Language name is "Rust"
Latest version 1.85

Tuple Structs

Tuple Structs – Store a collection of mixed data without named fields but just the datatype of the field. They are distinguished as a unique data type.

struct Color(u8,u8,u8);

{
    let color = Color(255,0,0,);
    println!("First value in tuple struct is {}", color.0);
}

Output

First value in tuple struct is 255

Loading