You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: main.rs
    path of file: ./repos/tere/src
    
    the code of the file until where you have to start completion: use crossterm::{cursor, execute, terminal};
use std::io::Write;

mod cli_args;

mod settings;
use settings::{DeprecationWarnings, TereSettings};

mod app_state;
use app_state::TereAppState;

mod first_run_check;
use first_run_check::check_first_run_with_prompt;

mod ui;
use ui::TereTui;

mod error;
use error::TereError;

mod panic_guard;
use panic_guard::GuardWithHook;

fn main() -> Result<(), TereError> {
    let cli_args = cli_args::get_cli_args()
        .try_get_matches()
        .unwrap_or_else(|err| {
            // custom error handling: clap writes '--help' and '--version'
            // to stdout by default, but we want to print those to stderr
            // as well to not interfere with the intended behavior of tere
            eprint!("{err}");
            std::process::exit(1);
        });

    //TODO: should this alternate screen etc initialization (and teardown) be done by the UI?
    //Now the mouse capture enabling (which is kind of similar) is handled there.
    execute!(std::io::stderr(), terminal::EnterAlternateScreen)?;
    let res: Result<(std::path::PathBuf, DeprecationWarnings), TereError> = {
        // Use guards to ensure that we disable raw mode, show the cursor and leave the alternate
        // screen, even in the event of a panic. We are using unwrap quite liberally here, but the
        // guards should ensure that everything is handled correctly in the very unlikely event
        // that terminal modification calls fail.
        let _guard = GuardWithHook::new(|| {
            execute!(std::io::stderr(), terminal::LeaveAlternateScreen).unwrap()
        });

        execute!(std::io::stderr(), cursor::Hide).unwrap();
        {
            let _guard = GuardWithHook::new(|| execute!(std::io::stderr(), cursor::Show).unwrap());

            terminal::enable_raw_mode().unwrap();
            {
                let _guard = GuardWithHook::new(|| terminal::disable_raw_mode().unwrap());

                // We are now inside the alternate screen, with the cursor hidden and raw mode
                // enabled. We can finally actually run the application.

                let mut stderr = std::io::stderr();
                stderr
                    .flush()
                    .map_err(TereError::from)
                    .and_then(|_| TereSettings::parse_cli_args(&cli_args))
                    .and_then(|(settings, warnings)| {
                        check_first_run_with_prompt(&settings, &mut stderr)?;
                        Ok((settings, warnings))
                    })
                    .and_then(|(settings, warnings)| {
                        TereAppState::init(settings, &warnings)
                            .and_then(|state| TereTui::init(state, &mut stderr))
                            // actually run the app and return the final path
                            .and_then(|mut ui| ui.main_event_loop())
                            .map(|final_path| (final_path, warnings))
                    })
            }
        }
    };

    // Check if there was an error
    let (final_path, warnings) = match res {
        Err(err) => {
            match err {
                // Print pretty error message if the error was in arg parsing
        
    
fn main() -> Result<(), TereError> {
    let cli_args = cli_args::get_cli_args()
        .try_get_matches()
        .unwrap_or_else(|err| {
            // custom error handling: clap writes '--help' and '--version'
            // to stdout by default, but we want to print those to stderr
            // as well to not interfere with the intended behavior of tere
            eprint!("{err}");
            std::process::exit(1);
        });

    //TODO: should this alternate screen etc initialization (and teardown) be done by the UI?
    //Now the mouse capture enabling (which is kind of similar) is handled there.
    execute!(std::io::stderr(), terminal::EnterAlternateScreen)?;
    let res: Result<(std::path::PathBuf, DeprecationWarnings), TereError> = {
        // Use guards to ensure that we disable raw mode, show the cursor and leave the alternate
        // screen, even in the event of a panic. We are using unwrap quite liberally here, but the
        // guards should ensure that everything is handled correctly in the very unlikely event
        // that terminal modification calls fail.
        let _guard = GuardWithHook::new(|| {
            execute!(std::io::stderr(), terminal::LeaveAlternateScreen).unwrap()
        });

        execute!(std::io::stderr(), cursor::Hide).unwrap();
        {
            let _guard = GuardWithHook::new(|| execute!(std::io::stderr(), cursor::Show).unwrap());

            terminal::enable_raw_mode().unwrap();
            {
                let _guard = GuardWithHook::new(|| terminal::disable_raw_mode().unwrap());

                // We are now inside the alternate screen, with the cursor hidden and raw mode
                // enabled. We can finally actually run the application.

                let mut stderr = std::io::stderr();
                stderr
                    .flush()
                    .map_err(TereError::from)
                    .and_then(|_| TereSettings::parse_cli_args(&cli_args))
                    .and_then(|(settings, warnings)| {
                        check_first_run_with_prompt(&settings, &mut stderr)?;
                        Ok((settings, warnings))
                    })
                    .and_then(|(settings, warnings)| {
                        TereAppState::init(settings, &warnings)
                            .and_then(|state| TereTui::init(state, &mut stderr))
                            // actually run the app and return the final path
                            .and_then(|mut ui| ui.main_event_loop())
                            .map(|final_path| (final_path, warnings))
                    })
            }
        }
    };

    // Check if there was an error
    let (final_path, warnings) = match res {
        Err(err) => {
            match err {
                // Print pretty error message if the error was in arg parsing
                TereError::Clap(e) => e.exit(),

                TereError::ExitWithoutCd(msg) | TereError::FirstRunPromptCancelled(msg) => {
                    eprintln!("{msg}");
                    std::process::exit(1);
                }

                // exit in case of any other error
                e => return Err(e),
            }
        }
        Ok(path) => path,
    };

    // Print warnings to stderr (in addition to displaying them in the UI on startup)
    for warning in warnings {
        eprintln!("Warning: {warning}");
    }

    // No error, print cwd, as returned by the app state
    println!("{}", final_path.display());

    Ok(())
}