Rust program for iced framework crashes on snapcraft

Ok I got it, my yaml is this:

name: autoskola3 # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '3.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Testing app for drivers with 2000 questions. # 79 char long summary
description: |
  This app offers 2000 questions in Slovak and English for drivers to be tested 
  before main exam in Slovak Republic. More on https://hrubos.org or 
  http://programujem.szm.sk Just download and be ready before driving exam.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
source-code: janko.hrubos@gmail.com


parts:
  autoskola3:
    # See 'snapcraft plugins'
    plugin: rust
    source: ./ 
    build-packages:
      - cargo
      - libssl-dev  
    stage-packages:
      - libxkbcommon-x11-0
apps:
  autoskola3:
    command: bin/autoskola3
    common-id: org.hrubos
    extensions: [gnome]
    plugs:
      - network

Some pics of running devel snap:

THANKS TO ALL FOR THE HELP!!! THE TOPIC IS CLOSED NOW.

1 Like

One last question: How long does it last pending review? Picture:

Thanks for everything :wink:

Typically a day or two. But only Canonical employees have access to this review process, so I don’t know how long the queue is. I expect (based on my recent experience) you’ll get an answer before the middle of the week.

Hey there, thanks, I finally created my snap, but during the push I get this error on your side:

Issues while processing snap:g                                                 
- __all__: Links must be http(s):// URLs.

I cant’t see any docu for this error. THANKS A LOT FOR THE HELP. Picture:

You have an email where a url should be. source-code is usually used to point to a url. If you want to use an email address, put that in a top level contact field. As per the documentation: Snapcraft top-level metadata | Snapcraft documentation

All right I just changes yaml to this:

name: autoskola3 # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '3.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Testing app for drivers with 2000 questions. # 79 char long summary
description: |
  This app offers 2000 questions in Slovak and English for drivers to be tested 
  before main exam in Slovak Republic. More on https://hrubos.org Just download and be ready before driving exam.

grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots



parts:
  autoskola3:
    # See 'snapcraft plugins'
    plugin: rust
    source: ./ 
    build-packages:
      - cargo
      - libssl-dev  
    stage-packages:
      - libxkbcommon-x11-0
apps:
  autoskola3:
    command: bin/autoskola3
    common-id: org.hrubos.autoskola3
    extensions: [gnome]
    plugs:
      - network

Now the output is this picture:

Seems to be it is finally there in the global market… THANKS A LOT.

1 Like

Well, another error, it did not attached my ./resources folder from which binary reads pictures, I tried layout: but it cant have layout: ./resources: $SNAP/local/resources, then I am reading about dump plugin, but I can’t find anywhere in docu how to add dump plugin to yaml. Any ideas how to allow ./resources folder in snap? My pic:

Thanks for the help: What to change in this yaml:

name: autoskola3 # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '3.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Testing app for drivers with 2000 questions. # 79 char long summary
description: |
  This app offers 2000 questions in Slovak and English for drivers to be tested 
  before main exam in Slovak Republic. More on https://hrubos.org Just download and be ready before driving exam.

grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots

parts:
  autoskola3:
    # See 'snapcraft plugins'
    plugin: rust    
    source: ./ 
    build-packages:
      - cargo
      - libssl-dev  
    stage-packages:
      - libxkbcommon-x11-0
  
apps:
  autoskola3:
    command: bin/autoskola3
    common-id: org.hrubos.autoskola3
    extensions: [gnome]
    plugs:
      - network

Ok I got it, I added dump plugin for local resources, picture:

My yaml is this:


name: autoskola3 # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '3.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Testing app for drivers with 2000 questions. # 79 char long summary
description: |
  This app offers 2000 questions in Slovak and English for drivers to be tested 
  before main exam in Slovak Republic. More on https://hrubos.org Just download and be ready before driving exam.
grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots
parts:
  autoskola3:
    # See 'snapcraft plugins'
    plugin: rust    
    source: ./ 
    build-packages:
      - cargo
      - libssl-dev  
    stage-packages:
      - libxkbcommon-x11-0
  autoskola3-resources:
    plugin: dump
    source: ./
apps:
  autoskola3:
    command: bin/autoskola3
    common-id: org.hrubos.autoskola3
    extensions: [gnome]
    plugs:
      - network

THIS IS FINAL SOLUTION, THANKS FOR EVERYTHING!!!

1 Like

Hi, after a week of using my snap in global store I’m on this error: My dump plugin files necessary being in snap are not there. I can’t read any data by compiled program in snap, result pic:

My dir struct is: ./autoskola3==reading: ./resources/en/t1o1.jpg But everything I can is to run the ./autoskola3 and as you see on the pic ^^^ upper the program inside the snap cant read anything. Why dump plugin does not work? Or what to use please?? Any ideas? Thanks.

well reading here: source: ./foo will include ALL files from foo in the snap, dumped (by dump plugin) into the base directory of the snap. link: The dump plugin - #4 by knobby and here: It is true that the target will end up be placing at the root of the snap file hierachy Then reading here: Layouts enable snap developers outside of locations referenced by $SNAP https://snapcraft.io/docs/the-snap-format Any ideas why I can read from local file system if used: snap install local_snap.snap --dangerous But I can’t read from $SNAP file system on global store installation: snap install autoskola3 Thanks for any ideas.

then reading here if I wanna check current exe folder and in this folder ./resources/ folder I get this: If the executable was invoked through a symbolic link, some platforms will return the path of the symbolic link and other platforms will return the path of the symbolic link’s target. Which is unusable functionhttps://doc.rust-lang.org/std/env/fn.current_exe.html Thanks for any other ideas.

All right reading here:

organize:
      qt5-launch: bin/qt5-launch

gonna try that… Dump Plugin - target path

All right reading also: organize: Snapcraft parts metadata | Snapcraft documentation not working just renaming Then reading how to insert files to snap: https://askubuntu.com/questions/739379/how-to-copy-source-files-into-stage-snap-with-snapcraft Also mentioned dump ./ And finally some howtos: Not working too: https://snapcraft.io/docs/snap-howto

So I’ve read also: this: How to copy just one file using the dump plugin? Then also this: Build and staging dependencies - #2 by mwhudson And also this: Parts lifecycle | Snapcraft documentation and this: https://snapcraft.io/docs/snapcraft-parts-metadata#heading--stage And finally I checked this yaml: snapd/build-aux/snap/snapcraft.yaml at master · snapcore/snapd · GitHub But stage did not help. My YAML is now:

name: autoskola3 # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '3.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Testing app for drivers with 2000 questions. # 79 char long summary
description: |
  This app offers 2000 questions in Slovak and English for drivers to be tested 
  before main exam in Slovak Republic. More on https://hrubos.org Just download and be ready before driving exam.
grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots
parts:
  autoskola3:
    # See 'snapcraft plugins'
    plugin: rust    
    source: ./ 
    build-packages:
      - cargo
      - libssl-dev  
    stage-packages:
      - libxkbcommon-x11-0
  autoskola3-resources:
    plugin: dump
    source: ./
  autoskola3-copy-resources:
    plugin: nil
    stage:
      - ./*
apps:
  autoskola3:
    command: bin/autoskola3
    common-id: org.hrubos.autoskola3
    extensions: [gnome]
    plugs:
      - network

Still getting this pic:

All right I created revision3 with staged resources. Seems to be error of Linux. The only way how to run the app is to open folder program /snap/autoskola3/3/autoskola3 manually. Otherwise the program crashes. Resources are present in this folder with program. Some pictures of the situation:

I dont understand why this does not work, if this is truth: At that point, the path you used to get to the file doesn't matter. https://unix.stackexchange.com/questions/26896/how-does-linux-work-with-symbolic-links The symlink points to the name of the real file (inode) in the file system.

Ok I tried to edit paths in source code of Rust and this is the fix, ok my snap should now work without crashes Pics:

Rust source code is now:

use iced::{
    widget::{column, image, text, button, row},
     Sandbox, Settings, Color, Alignment, Length,
};//use crates of iced framework
use rand::prelude::*; //use crate of rand 
use std::fs; //use file system crate
//use std::env::current_dir;
//use std::path::PathBuf;


//function giving me random number from 1 to right_border
fn rand_range_num(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (1..right_border).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//function giving me the random number from right_border to 288
fn rand_range_num2(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..288).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num3(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..23).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num4(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..27).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//function returning the current directory of exe/elf
fn cur_dir1()->String{
	//let path = current_dir().unwrap();
	//path.display().to_string().clone()
	let path = process_path::get_executable_path();
	//let srcdir = PathBuf::from("./");
	//fs::canonicalize(&srcdir).expect("Error returning the path from fs:: module... ").into_os_string().into_string().unwrap()
	match path {
		None => String::from("The process path could not be determined... "),
		Some(path) => {
			let len = path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").chars().count() - 11;
			path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").drain(0..len).collect::<String>()
			//path.into_os_string().into_string().unwrap()
		}
	}
}

//calling main function in rust language
fn main() -> iced::Result {
    MyApp::run(Settings::default())
}
//enum with app signals definitions:
#[derive(Debug, Clone)]
enum MyAppMessage {
    GoZakon,
    GoZnacka,
    GoKrizovatka,
    GiveAnswer,
    GoLaw,
    GoSign,
    GoIntersection
}
//state of the application based on iced framework documentation:
#[derive(Default)]
struct MyApp{
	pic_value:String,
	question_value:String,
	answer_value:String,
	q_num:String,
	t_num:String,
	q_type:String,
	}
//implementation for myapp struct:
impl Sandbox for MyApp {
    type Message = MyAppMessage;//type alias
    //app window constructor:
    fn new() -> Self {
        Self{
			pic_value: String::from(""),
			question_value: String::from("Sem načítam otázku po kliknutí na príslušné tlačítko...\n Here I load the question after adequate button click..."),
			answer_value: String::from("Sem načítam odpoveď po kliknutí na príslušné tlačítko...\n Here I load the answer after adequate button click..."),
			q_num: String::from("1"), //global random number of the SLOVAK question
			q_type: String::from("za"), //whether zakony za or znacky zn
			t_num:String::from("1"), //just the first English test as we know t1o1.txt means test1 otazka1
		}
    }
    //title of app window:
    fn title(&self) -> String {
        String::from("Autoškola3 EN+SK: 2000 questions | Mgr. Janko Hruboš | janko.hrubos@gmail.com")
    }
    //on the state update and signals receiving do these actions:
    fn update(&mut self, message: Self::Message) {
		 match message {
            MyAppMessage::GoZakon => {
				
                self.pic_value = cur_dir1()+"/resources/empty.jpg";
                //println!("{}",cur_dir1());
                self.q_num=rand_range_num(525);                 
                let mut s2:String=cur_dir1()+"/resources/sk/otza/za_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("za");
				self.answer_value=String::from("");
								
                //^^^ self explanatory
            }
            MyAppMessage::GoZnacka => {                
                self.q_num=rand_range_num(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("zn");
				self.answer_value=String::from("");
                              
            }
            
            MyAppMessage::GoKrizovatka => {
                self.q_num=rand_range_num2(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("kri");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoLaw => {
				self.q_num=rand_range_num(15);//generate random question from 1 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                //let s4:String=("resources/en/znackyobr/z".to_owned()+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = String::from(cur_dir1()+"/resources/empty.jpg");
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("law");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoSign => {
                self.q_num=rand_range_num3(16);//generate random question from 16 to 23
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("sig");
				self.answer_value=String::from("");
                
                
            }
            MyAppMessage::GoIntersection => {
                self.q_num=rand_range_num4(24);//generate random question from 24 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1()));
				self.q_type=String::from("int");//question type is intersection
				self.answer_value=String::from("");//answer is not visible yet, coz intersection button pressed not answer button
                //^^^ self explanatory what to do on these signals receiving
                
            }
            MyAppMessage::GiveAnswer => { //on button answer click:
				let qnum = self.q_num.clone();
				let tnum = self.t_num.clone();
				let qtype = self.q_type.clone();
				if qtype == "za" { //if this is Slovak zakon you know qnum is from 1 to 525
					let mut s2:String=cur_dir1()+"/resources/sk/otza/zao_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku zákony ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "zn" { //if this is Slovak znacka you know qnum is from 1 to 144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku značky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "kri" { //if this is Slovak znacka you know qnum is from (1 to 144)+144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku križovatky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "law" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from laws ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "sig" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from signs ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "int" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from intersections ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1())));
					
				}
				
                
            }
            
        }
		
		}
	//basic view definitions with slots of signals:
    fn view(&self) -> iced::Element<'_, Self::Message> {
        let padding1:u16=10;//padding of 10px
        column![ 	  
            image(self.pic_value.clone()).width(600),
            row![button("Náhodný zákon").on_press(MyAppMessage::GoZakon).padding(padding1),
            button("Náhodná značka").on_press(MyAppMessage::GoZnacka).padding(padding1),
            button("Náhodná križovatka").on_press(MyAppMessage::GoKrizovatka).padding(padding1)],
            row![button("Answer/Opoveď").on_press(MyAppMessage::GiveAnswer).padding(padding1)],
            row![button("Random law").on_press(MyAppMessage::GoLaw).padding(padding1),
            button("Random sign").on_press(MyAppMessage::GoSign).padding(padding1),
            button("Random intersection").on_press(MyAppMessage::GoIntersection).padding(padding1),],
            text(self.question_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
            text(self.answer_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
        ].width(Length::Fill).align_items(Alignment::Center).padding(20)
        .into()
    }
}

And YAML file is now:

name: autoskola3 # you probably want to 'snapcraft register <name>'
base: core22 # the base snap is the execution environment for this snap
version: '3.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Testing app for drivers with 2000 questions. # 79 char long summary
description: |
  This app offers 2000 questions in Slovak and English for drivers to be tested 
  before main exam in Slovak Republic. More on https://hrubos.org Just download and be ready before driving exam.
grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots
parts:
  autoskola3:
    # See 'snapcraft plugins'
    plugin: rust    
    source: ./ 
    build-packages:
      - cargo
      - libssl-dev  
    stage-packages:
      - libxkbcommon-x11-0
  autoskola3-resources:
    plugin: dump
    source: ./
  autoskola3-copy-resources:
    plugin: nil
    stage:
      - ./*
apps:
  autoskola3:
    command: bin/autoskola3
    common-id: org.hrubos.autoskola3
    extensions: [gnome]
    plugs:
      - network

I’ll check it in snapcraft, but elf run paths are fixed!

Finally one more problem arised and it was -11 delta of chars in rust function cur_dir1(), coz we have in path 1Byte and 2Byte chars. So final main.rs Rust code looks like:

use iced::{
    widget::{column, image, text, button, row},
     Sandbox, Settings, Color, Alignment, Length,
};//use crates of iced framework
use rand::prelude::*; //use crate of rand 
use std::fs; //use file system crate
//use std::env::current_dir;
//use std::path::PathBuf;
//use std::path::Path;
use pathtrim::TrimmablePath;


//function giving me random number from 1 to right_border
fn rand_range_num(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (1..right_border).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//function giving me the random number from right_border to 288
fn rand_range_num2(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..288).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num3(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..23).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num4(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..27).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}

//function returning the current directory of exe/elf
fn cur_dir1()->String{
	//let path = current_dir().unwrap();
	//path.display().to_string().clone()
	let path = process_path::get_executable_path();
	//let srcdir = PathBuf::from("./");
	//fs::canonicalize(&srcdir).expect("Error returning the path from fs:: module... ").into_os_string().into_string().unwrap()
	match path {
		None => String::from("The process path could not be determined... "),
		Some(path) => {
			let len = path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").chars().count();
			let outa_path_exe=path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").drain(0..len).collect::<String>();
			//let to_replace = path.trim_to_nth(1).expect("Can not trim the path. ").into_os_string().into_string().unwrap();
			//let target_str = outa_path_exe.replace(to_replace.as_str(),"");
			let to_replace=String::from("/");
			let mut del_farther:usize=0;
			if let Some(last_index) = outa_path_exe.as_str().rfind(&to_replace.as_str()) {
				del_farther = last_index;
			}
			outa_path_exe.as_str()[0..del_farther].to_string()+"/"
			//path.trim_to_nth(1).expect("Can not trim the path. ").into_os_string().into_string().unwrap()
			//target_str.to_string()			
		}
	}
}

//calling main function in rust language
fn main() -> iced::Result {
    MyApp::run(Settings::default())
}
//enum with app signals definitions:
#[derive(Debug, Clone)]
enum MyAppMessage {
    GoZakon,
    GoZnacka,
    GoKrizovatka,
    GiveAnswer,
    GoLaw,
    GoSign,
    GoIntersection
}
//state of the application based on iced framework documentation:
#[derive(Default)]
struct MyApp{
	pic_value:String,
	question_value:String,
	answer_value:String,
	q_num:String,
	t_num:String,
	q_type:String,
	}
//implementation for myapp struct:
impl Sandbox for MyApp {
    type Message = MyAppMessage;//type alias
    //app window constructor:
    fn new() -> Self {
        Self{
			pic_value: String::from(""),
			question_value: String::from("Sem načítam otázku po kliknutí na príslušné tlačítko...\n Here I load the question after adequate button click..."),
			answer_value: String::from("Sem načítam odpoveď po kliknutí na príslušné tlačítko...\n Here I load the answer after adequate button click..."),
			q_num: String::from("1"), //global random number of the SLOVAK question
			q_type: String::from("za"), //whether zakony za or znacky zn
			t_num:String::from("1"), //just the first English test as we know t1o1.txt means test1 otazka1
		}
    }
    //title of app window:
    fn title(&self) -> String {
        String::from("Autoškola3 EN+SK: 2000 questions | Mgr. Janko Hruboš | janko.hrubos@gmail.com")
    }
    //on the state update and signals receiving do these actions:
    fn update(&mut self, message: Self::Message) {
		 match message {
            MyAppMessage::GoZakon => {
				
                self.pic_value = cur_dir1()+"/resources/empty.jpg";
                //println!("{}",cur_dir1());
                self.q_num=rand_range_num(525);                 
                let mut s2:String=cur_dir1()+"/resources/sk/otza/za_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("za");
				self.answer_value=String::from("");
								
                //^^^ self explanatory
            }
            MyAppMessage::GoZnacka => {                
                self.q_num=rand_range_num(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("zn");
				self.answer_value=String::from("");
                              
            }
            
            MyAppMessage::GoKrizovatka => {
                self.q_num=rand_range_num2(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("kri");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoLaw => {
				self.q_num=rand_range_num(15);//generate random question from 1 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                //let s4:String=("resources/en/znackyobr/z".to_owned()+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = String::from(cur_dir1()+"/resources/empty.jpg");
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("law");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoSign => {
                self.q_num=rand_range_num3(16);//generate random question from 16 to 23
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("sig");
				self.answer_value=String::from("");
                
                
            }
            MyAppMessage::GoIntersection => {
                self.q_num=rand_range_num4(24);//generate random question from 24 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1()));
				self.q_type=String::from("int");//question type is intersection
				self.answer_value=String::from("");//answer is not visible yet, coz intersection button pressed not answer button
                //^^^ self explanatory what to do on these signals receiving
                
            }
            MyAppMessage::GiveAnswer => { //on button answer click:
				let qnum = self.q_num.clone();
				let tnum = self.t_num.clone();
				let qtype = self.q_type.clone();
				if qtype == "za" { //if this is Slovak zakon you know qnum is from 1 to 525
					let mut s2:String=cur_dir1()+"/resources/sk/otza/zao_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku zákony ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "zn" { //if this is Slovak znacka you know qnum is from 1 to 144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku značky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "kri" { //if this is Slovak znacka you know qnum is from (1 to 144)+144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku križovatky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "law" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from laws ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "sig" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from signs ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "int" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from intersections ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1())));
					
				}
				
                
            }
            
        }
		
		}
	//basic view definitions with slots of signals:
    fn view(&self) -> iced::Element<'_, Self::Message> {
        let padding1:u16=10;//padding of 10px
        column![ 	  
            image(self.pic_value.clone()).width(600),
            row![button("Náhodný zákon").on_press(MyAppMessage::GoZakon).padding(padding1),
            button("Náhodná značka").on_press(MyAppMessage::GoZnacka).padding(padding1),
            button("Náhodná križovatka").on_press(MyAppMessage::GoKrizovatka).padding(padding1)],
            row![button("Answer/Opoveď").on_press(MyAppMessage::GiveAnswer).padding(padding1)],
            row![button("Random law").on_press(MyAppMessage::GoLaw).padding(padding1),
            button("Random sign").on_press(MyAppMessage::GoSign).padding(padding1),
            button("Random intersection").on_press(MyAppMessage::GoIntersection).padding(padding1),],
            text(self.question_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
            text(self.answer_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
        ].width(Length::Fill).align_items(Alignment::Center).padding(20)
        .into()
    }
}

And cargo.toml file looks like:

[package]
name = "autoskola3"
version = "3.0.0"
authors = ["Mgr. Jan Hrubos <janko.hrubos@gmail.com>"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
iced = { version = "0.12.1", features = ["image"] }
rand = { version = "0.8.5"}
process_path = { version = "0.1.4" }
pathtrim = "2.0.0"

Now I’m gonna test it in snapstore ^^^

All right I tested it, it didnt work, I had to snapcraft clean command and then to edit YAML file. Now this looks like this:

Now my YAML file looks like this and finally works in snapstore:

name: autoskola4 # you probably want to 'snapcraft register <name>'
base: core20 # the base snap is the execution environment for this snap
version: '4.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Testing app for drivers with 2000 questions. # 79 char long summary
description: |
  This app offers 2000 questions in Slovak and English for drivers to be tested 
  before main exam in Slovak Republic. More on https://hrubos.org Just download and be ready before driving exam.
grade: stable # must be 'stable' to release into candidate/stable channels
confinement: strict # use 'strict' once you have the right plugs and slots
parts:
  autoskola4:
    # See 'snapcraft plugins'
    plugin: rust    
    source: ./ 
    build-packages:
      - cargo
      - libssl-dev  
    stage-packages:
      - libxkbcommon-x11-0
  autoskola4-resources:
    plugin: dump
    source: ./ 
    organize:
      resources: bin/resources/     
  autoskola4-copy-resources:
    plugin: nil
    stage:
      - ./*
apps:
  autoskola4:
    command: bin/autoskola4
    common-id: org.hrubos.autoskola4
    extensions: [gnome-3-38]
    plugs:
      - network
      - home

My cargo TOML file looks like this:

[package]
name = "autoskola4"
version = "4.0.0"
authors = ["Mgr. Jan Hrubos <janko.hrubos@gmail.com>"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
iced = { version = "0.12.1", features = ["image"] }
rand = { version = "0.8.5"}
process_path = { version = "0.1.4" }
pathtrim = "2.0.0"

And my Rust main.rs looks like this:

use iced::{
    widget::{column, image, text, button, row},
     Sandbox, Settings, Color, Alignment, Length,
};//use crates of iced framework
use rand::prelude::*; //use crate of rand 
use std::fs; //use file system crate
//use std::env::current_dir;
//use std::path::PathBuf;
//use std::path::Path;
//use pathtrim::TrimmablePath;


//function giving me random number from 1 to right_border
fn rand_range_num(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (1..right_border).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//function giving me the random number from right_border to 288
fn rand_range_num2(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..288).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num3(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..23).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num4(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..27).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}

//function returning the current directory of exe/elf
fn cur_dir1()->String{
	//let path = current_dir().unwrap();
	//path.display().to_string().clone()
	let path = process_path::get_executable_path();
	//let srcdir = PathBuf::from("./");
	//fs::canonicalize(&srcdir).expect("Error returning the path from fs:: module... ").into_os_string().into_string().unwrap()
	match path {
		None => String::from("The process path could not be determined... "),
		Some(path) => {
			let len = path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").chars().count();
			let outa_path_exe=path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").drain(0..len).collect::<String>();
			//let to_replace = path.trim_to_nth(1).expect("Can not trim the path. ").into_os_string().into_string().unwrap();
			//let target_str = outa_path_exe.replace(to_replace.as_str(),"");
			let to_replace=String::from("/");
			let mut del_farther:usize=0;
			if let Some(last_index) = outa_path_exe.as_str().rfind(&to_replace.as_str()) {
				del_farther = last_index;
			}
			outa_path_exe.as_str()[0..del_farther].to_string()+"/"
			//path.trim_to_nth(1).expect("Can not trim the path. ").into_os_string().into_string().unwrap()
			//target_str.to_string()			
		}
	}
}

//calling main function in rust language
fn main() -> iced::Result {
    MyApp::run(Settings::default())
}
//enum with app signals definitions:
#[derive(Debug, Clone)]
enum MyAppMessage {
    GoZakon,
    GoZnacka,
    GoKrizovatka,
    GiveAnswer,
    GoLaw,
    GoSign,
    GoIntersection
}
//state of the application based on iced framework documentation:
#[derive(Default)]
struct MyApp{
	pic_value:String,
	question_value:String,
	answer_value:String,
	q_num:String,
	t_num:String,
	q_type:String,
	}
//implementation for myapp struct:
impl Sandbox for MyApp {
    type Message = MyAppMessage;//type alias
    //app window constructor:
    fn new() -> Self {
        Self{
			pic_value: String::from(""),
			question_value: String::from("Sem načítam otázku po kliknutí na príslušné tlačítko...\n Here I load the question after adequate button click..."),
			answer_value: String::from("Sem načítam odpoveď po kliknutí na príslušné tlačítko...\n Here I load the answer after adequate button click..."),
			q_num: String::from("1"), //global random number of the SLOVAK question
			q_type: String::from("za"), //whether zakony za or znacky zn
			t_num:String::from("1"), //just the first English test as we know t1o1.txt means test1 otazka1
		}
    }
    //title of app window:
    fn title(&self) -> String {
        String::from("Autoškola4 EN+SK: 2000 questions | Mgr. Janko Hruboš | janko.hrubos@gmail.com")
    }
    //on the state update and signals receiving do these actions:
    fn update(&mut self, message: Self::Message) {
		 match message {
            MyAppMessage::GoZakon => {
				
                self.pic_value = cur_dir1()+"/resources/empty.jpg";
                //println!("{}",cur_dir1());
                self.q_num=rand_range_num(525);                 
                let mut s2:String=cur_dir1()+"/resources/sk/otza/za_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("za");
				self.answer_value=String::from("");
								
                //^^^ self explanatory
            }
            MyAppMessage::GoZnacka => {                
                self.q_num=rand_range_num(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("zn");
				self.answer_value=String::from("");
                              
            }
            
            MyAppMessage::GoKrizovatka => {
                self.q_num=rand_range_num2(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("kri");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoLaw => {
				self.q_num=rand_range_num(15);//generate random question from 1 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                //let s4:String=("resources/en/znackyobr/z".to_owned()+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = String::from(cur_dir1()+"/resources/empty.jpg");
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("law");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoSign => {
                self.q_num=rand_range_num3(16);//generate random question from 16 to 23
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("sig");
				self.answer_value=String::from("");
                
                
            }
            MyAppMessage::GoIntersection => {
                self.q_num=rand_range_num4(24);//generate random question from 24 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1()));
				self.q_type=String::from("int");//question type is intersection
				self.answer_value=String::from("");//answer is not visible yet, coz intersection button pressed not answer button
                //^^^ self explanatory what to do on these signals receiving
                
            }
            MyAppMessage::GiveAnswer => { //on button answer click:
				let qnum = self.q_num.clone();
				let tnum = self.t_num.clone();
				let qtype = self.q_type.clone();
				if qtype == "za" { //if this is Slovak zakon you know qnum is from 1 to 525
					let mut s2:String=cur_dir1()+"/resources/sk/otza/zao_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku zákony ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "zn" { //if this is Slovak znacka you know qnum is from 1 to 144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku značky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "kri" { //if this is Slovak znacka you know qnum is from (1 to 144)+144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku križovatky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "law" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from laws ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "sig" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from signs ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "int" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from intersections ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1())));
					
				}
				
                
            }
            
        }
		
		}
	//basic view definitions with slots of signals:
    fn view(&self) -> iced::Element<'_, Self::Message> {
        let padding1:u16=10;//padding of 10px
        column![ 	  
            image(self.pic_value.clone()).width(600),
            row![button("Náhodný zákon").on_press(MyAppMessage::GoZakon).padding(padding1),
            button("Náhodná značka").on_press(MyAppMessage::GoZnacka).padding(padding1),
            button("Náhodná križovatka").on_press(MyAppMessage::GoKrizovatka).padding(padding1)],
            row![button("Answer/Opoveď").on_press(MyAppMessage::GiveAnswer).padding(padding1)],
            row![button("Random law").on_press(MyAppMessage::GoLaw).padding(padding1),
            button("Random sign").on_press(MyAppMessage::GoSign).padding(padding1),
            button("Random intersection").on_press(MyAppMessage::GoIntersection).padding(padding1),],
            text(self.question_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
            text(self.answer_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
        ].width(Length::Fill).align_items(Alignment::Center).padding(20)
        .into()
    }
}

Now everything is tested in snapstore and with local paths. Should work now ok. If you want to download it in zip it is here: https://hrubos.org/repo/autoskola4_and_snap.zip

For windows11 the code of cur_dir1() function is this:

So the code of main.rs for windows11 is:

use iced::{
    widget::{column, image, text, button, row},
     Sandbox, Settings, Color, Alignment, Length,
};//use crates of iced framework
use rand::prelude::*; //use crate of rand 
use std::fs; //use file system crate
//use std::env::current_dir;
//use std::path::PathBuf;
//use std::path::Path;
//use pathtrim::TrimmablePath;
use  std::env::current_exe;


//function giving me random number from 1 to right_border
fn rand_range_num(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (1..right_border).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//function giving me the random number from right_border to 288
fn rand_range_num2(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..288).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num3(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..23).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}
//same like ^^^
fn rand_range_num4(right_border:i32)-> String{
	let mut rng = rand::thread_rng();
	let mut nums: Vec<i32> = (right_border..27).collect();
	nums.shuffle(&mut rng);
	nums[0].to_string()
}

//function returning the current directory of exe/elf
fn cur_dir1()->String{
	//let path = current_dir().unwrap();
	//path.display().to_string().clone()
	// /*>>linux process only path:*/ let path = process_path::get_executable_path();
	let path = current_exe(); //for windows 11
	//let srcdir = PathBuf::from("./");
	//fs::canonicalize(&srcdir).expect("Error returning the path from fs:: module... ").into_os_string().into_string().unwrap()
	//windows path only:
	match path {
    Ok(exe_path) =>  {
		let exe_path = exe_path.display().to_string();
		let to_replace=String::from("\\");
		let mut del_farther:usize=0;
			if let Some(last_index) = exe_path.as_str().rfind(&to_replace.as_str()) {
				del_farther = last_index;
			}
		return exe_path.as_str()[0..del_farther].to_string()+"\\"	
		},
    Err(e) => return String::from("Failed to get current exe path {e} "),
	};
	//linux process only path
	/*
	match path {
		None => String::from("The process path could not be determined... "),
		Some(path) => {
			let len = path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").chars().count();
			let outa_path_exe=path.clone().into_os_string().into_string().expect("Can not shorten path of 10 chars from end == minus autoskola3").drain(0..len).collect::<String>();
			//let to_replace = path.trim_to_nth(1).expect("Can not trim the path. ").into_os_string().into_string().unwrap();
			//let target_str = outa_path_exe.replace(to_replace.as_str(),"");
			let to_replace=String::from("/");
			let mut del_farther:usize=0;
			if let Some(last_index) = outa_path_exe.as_str().rfind(&to_replace.as_str()) {
				del_farther = last_index;
			}
			outa_path_exe.as_str()[0..del_farther].to_string()+"/"
			//path.trim_to_nth(1).expect("Can not trim the path. ").into_os_string().into_string().unwrap()
			//target_str.to_string()			
		}	
	} */ }

//calling main function in rust language
fn main() -> iced::Result {
    MyApp::run(Settings::default())
}
//enum with app signals definitions:
#[derive(Debug, Clone)]
enum MyAppMessage {
    GoZakon,
    GoZnacka,
    GoKrizovatka,
    GiveAnswer,
    GoLaw,
    GoSign,
    GoIntersection
}
//state of the application based on iced framework documentation:
#[derive(Default)]
struct MyApp{
	pic_value:String,
	question_value:String,
	answer_value:String,
	q_num:String,
	t_num:String,
	q_type:String,
	}
//implementation for myapp struct:
impl Sandbox for MyApp {
    type Message = MyAppMessage;//type alias
    //app window constructor:
    fn new() -> Self {
        Self{
			pic_value: String::from(""),
			question_value: String::from("Sem načítam otázku po kliknutí na príslušné tlačítko...\n Here I load the question after adequate button click..."),
			answer_value: String::from("Sem načítam odpoveď po kliknutí na príslušné tlačítko...\n Here I load the answer after adequate button click..."),
			q_num: String::from("1"), //global random number of the SLOVAK question
			q_type: String::from("za"), //whether zakony za or znacky zn
			t_num:String::from("1"), //just the first English test as we know t1o1.txt means test1 otazka1
		}
    }
    //title of app window:
    fn title(&self) -> String {
        String::from("Autoškola2023 EN+SK: 2000 questions | Mgr. Janko Hruboš | janko.hrubos@gmail.com")
    }
    //on the state update and signals receiving do these actions:
    fn update(&mut self, message: Self::Message) {
		 match message {
            MyAppMessage::GoZakon => {
				
                self.pic_value = cur_dir1()+"/resources/empty.jpg";
                //println!("{}",cur_dir1());
                self.q_num=rand_range_num(525);                 
                let mut s2:String=cur_dir1()+"/resources/sk/otza/za_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("za");
				self.answer_value=String::from("");
								
                //^^^ self explanatory
            }
            MyAppMessage::GoZnacka => {                
                self.q_num=rand_range_num(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("zn");
				self.answer_value=String::from("");
                              
            }
            
            MyAppMessage::GoKrizovatka => {
                self.q_num=rand_range_num2(144);                                 
                let s4:String=(cur_dir1()+"/resources/sk/znackyobr/z"+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/sk/otzn/z_";
                let s3:String=".txt".to_owned();
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("kri");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoLaw => {
				self.q_num=rand_range_num(15);//generate random question from 1 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                //let s4:String=("resources/en/znackyobr/z".to_owned()+&self.q_num+".jpg").to_string().clone();                
                self.pic_value = String::from(cur_dir1()+"/resources/empty.jpg");
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("law");
				self.answer_value=String::from("");
            }
            MyAppMessage::GoSign => {
                self.q_num=rand_range_num3(16);//generate random question from 16 to 23
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect("ERROR: Cant read the file, sorry...");
				self.q_type=String::from("sig");
				self.answer_value=String::from("");
                
                
            }
            MyAppMessage::GoIntersection => {
                self.q_num=rand_range_num4(24);//generate random question from 24 to 27
				self.t_num=rand_range_num(35);//generate random test from 1 to 35
                let s4:String=(cur_dir1()+"/resources/en/znackyobr/t"+&self.t_num+"o"+&self.q_num+".jpg").to_string().clone();                
                //println!("{}",s4); //debug printout
                self.pic_value = s4;
                let mut s2:String=cur_dir1()+"/resources/en/otazkytxt/t";
                let s3:String=".txt".to_owned();
                let s5:String="o".to_owned();
                s2.push_str(&self.t_num);
                s2.push_str(&s5);
                s2.push_str(&self.q_num);
                s2.push_str(&s3); 
                self.question_value = fs::read_to_string(s2)
					.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1()));
				self.q_type=String::from("int");//question type is intersection
				self.answer_value=String::from("");//answer is not visible yet, coz intersection button pressed not answer button
                //^^^ self explanatory what to do on these signals receiving
                
            }
            MyAppMessage::GiveAnswer => { //on button answer click:
				let qnum = self.q_num.clone();
				let tnum = self.t_num.clone();
				let qtype = self.q_type.clone();
				if qtype == "za" { //if this is Slovak zakon you know qnum is from 1 to 525
					let mut s2:String=cur_dir1()+"/resources/sk/otza/zao_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku zákony ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "zn" { //if this is Slovak znacka you know qnum is from 1 to 144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku značky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "kri" { //if this is Slovak znacka you know qnum is from (1 to 144)+144
					let mut s2:String=cur_dir1()+"/resources/sk/otzn/zo_";
					let s3:String=".txt".to_owned();
					s2.push_str(&qnum);
					s2.push_str(&s3);
					self.answer_value=String::from("Odpoveď na otázku križovatky ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" je: ".to_owned();
					self.answer_value.push_str(&s4);
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "law" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from laws ");
					self.answer_value.push_str(&qnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "sig" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from signs ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect("ERROR: Cant read the file, sorry..."));
					
				}
				
				if qtype == "int" { 
					let mut s2:String=cur_dir1()+"/resources/en/odtxt/t";
					//let s3:String=".txt".to_owned();
					let s5:String="od".to_owned();
					s2.push_str(&tnum);
					s2.push_str(&s5);
					s2.push_str(&qnum);
					//s2.push_str(&s3);
					self.answer_value=String::from("Answer to the question from intersections ");
					self.answer_value.push_str(&qnum); 
					self.answer_value.push_str(" / test ");
					self.answer_value.push_str(&tnum); 
					let s4:String=" is: ".to_owned();
					self.answer_value.push_str(&s4);
					//println!("{}",s2);					
					self.answer_value.push_str(&fs::read_to_string(s2)
						.expect(&("ERROR: Cant read the file, sorry... Path: ".to_owned()+&cur_dir1())));
					
				}
				
                
            }
            
        }
		
		}
	//basic view definitions with slots of signals:
    fn view(&self) -> iced::Element<'_, Self::Message> {
        let padding1:u16=10;//padding of 10px
        column![ 	  
            image(self.pic_value.clone()).width(600),
            row![button("Náhodný zákon").on_press(MyAppMessage::GoZakon).padding(padding1),
            button("Náhodná značka").on_press(MyAppMessage::GoZnacka).padding(padding1),
            button("Náhodná križovatka").on_press(MyAppMessage::GoKrizovatka).padding(padding1)],
            row![button("Answer/Opoveď").on_press(MyAppMessage::GiveAnswer).padding(padding1)],
            row![button("Random law").on_press(MyAppMessage::GoLaw).padding(padding1),
            button("Random sign").on_press(MyAppMessage::GoSign).padding(padding1),
            button("Random intersection").on_press(MyAppMessage::GoIntersection).padding(padding1),],
            text(self.question_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
            text(self.answer_value.as_str()).style(Color::from_rgb(1., 0.0, 0.0)),
        ].width(Length::Fill).align_items(Alignment::Center).padding(20)
        .into()
    }
}

The pack for windows11 can be downloaded here: https://hrubos.org/repo/autoskola2023_win11.64_pack.zip