#how to concatenate two soroban string together

24 messages · Page 1 of 1 (latest)

solar galleon
#

How to concatenate two soroban string together

crude turtle
#

you can either use an allocator with the alloc feature that will give you some rust lib functions or use Bytes::extend_from_slice

let mut concat_str = Bytes::new(&env);
concat_str.extend_from_slice(my_str.as_bytes());
concat_str.extend_from_slice(my_u8_array.as_slice());
concat_str.extend_from_slice("litteral".as_bytes());
#

and then convert back Bytes to str and String

solar galleon
#

I have a soroban string object that I have created

#

How can I concatenate to that exiting soroban string

#

Yours is starting from bytes to string

#

I am starting from string.

crude turtle
#

then first use String::copy_into_slice to get a u8 array/slice, use Bytes::extend_from_slice, convert back Bytes::copy_into_slice to get a slice, convert to str then create a new String.
Here is something I'm using:

            const BASE: &str = "http://localhost:3000/test/";
            let d = to_hex(token_id);

            // concat
            let mut uri = Bytes::new(&env);
            uri.extend_from_slice(BASE.as_bytes());
            uri.extend_from_slice(d.as_slice());
            uri.extend_from_slice(".json".as_bytes());

            // Bytes to &str
            let mut slice = [0; BASE.len() + 10];
            uri.copy_into_slice(&mut slice);
            let struri = core::str::from_utf8(slice.as_slice()).unwrap();

            String::from_slice(&env, struri)
solar galleon
#

Just to concatenate

#

Yours is starting with &str.

As I said earlier. Mine is starting with soroban::String

#

Could you do an example that starts with that

frigid scaffold
#

Hello, has anyone managed to concatenate two soroban_sdk::String?

crude turtle
#

have you tried with the above example ?

frigid scaffold
#

Yes, let me show you:

use crate::base32;
use soroban_sdk::{Bytes, Env, String};

pub fn generate(e: &Env, did_method: &String) -> String {
    let random_bytes: [u8; 15] = get_random_bytes(e);
    let mut method_specific_id = [0u8; 24];

    base32::encode(&mut method_specific_id, &random_bytes);

    // concat
    let mut did_uri = Bytes::new(e);
    did_uri.extend_from_slice("did:".as_bytes());

    // MISSING: did_uri.extend_from_slice(did_method_slice)

    // Here I get an error: "attempt to use a non-constant value in a constant"
    // The `did_method` is a soroban_sdk::String so its size is not known at compile time.
    // How to solve that?
    let did_method_slice = [0; did_method.len()];
    did_method.copy_into_slice(&mut did_method_slice);
    did_uri.extend_from_slice(&did_method_slice);

    did_uri.extend_from_slice(&method_specific_id);

    // Bytes to &str
    let mut slice = [0; 4 + did_method.len() + 24]; // same error here: attempt to use a non-constant value in a constant
    did_uri.copy_into_slice(&mut slice);
    let str_did_uri = core::str::from_utf8(slice.as_slice()).unwrap();

    String::from_slice(e, str_did_uri)
}
#

@crude turtle notice that your example starts with const BASE: &str which 1. it's an &str and 2. it's a const.

Could you please help me to achieve this concatenation?

crude turtle
#

the important part is the extend_from_slice from Bytes, then Bytes to str then to String again

frigid scaffold
#

I understand, but would you know how to convert a soroban_sdk::String to &[u8] (which is what the extend_from_slice function expects)? 🤔
That's not clear to me

frail whale
#

Convert them to vals first

#

Then convert back to string

#

If u dont figure it out i can try to test it later today. I think there was example of concating bytes in the base32 example i gave u too.

south badger
#
pub fn concat_strings(
    env: Env
) -> String {
    let str1 = String::from_slice(&env, &"Hello ");
    let str2 = String::from_slice(&env, &"World!");

    let str1_len = str1.len() as usize;
    let str2_len = str2.len() as usize;
    let combined_len = str1_len + str2_len;

    let mut slice: [u8; 100] = [0; 100]; // should be big enough for both strings combined
    str1.copy_into_slice(&mut slice[..str1_len]);
    str2.copy_into_slice(&mut slice[str1_len..combined_len]);

    let final_string = String::from_slice(&env, core::str::from_utf8(&slice[..combined_len]).unwrap());

    final_string
}
frigid scaffold
#

thanks everyone! 🤟

ebon burrow