Расширять тильду в Rust Path идиоматически

Если вы хотите перенести веб-сайт в новый домен, чем просто настроить базу кода на новом сервере и внести соответствующие изменения в домен, он будет работать.

Во-вторых, если вы хотите просто показать веб-сайт в новом домене, но внутренне он все еще доступен в старом домене, чем вы можете использовать любой обратный прокси-сервер, такой как nginx, и использовать старый домен в качестве бэкэнд и ваш новый домен как его интерфейс.

1
задан Andrey Tyukin 22 January 2019 в 11:36
поделиться

1 ответ

  1. Наиболее идиоматичным способом было бы просто использовать существующий ящик, в этом случае shellexpand ( github , crates.io ), кажется, делает что вы хотите:

    extern crate shellexpand; // 1.0.0
    
    #[test]
    fn test_shellexpand() {
        let home = std::env::var("HOME").unwrap();
        assert_eq!(shellexpand::tilde("~/foo"), format!("{}/foo", home));
    }
    
  2. В качестве альтернативы, вы можете попробовать его с dirs ( crates.io ). Вот эскиз:

    extern crate dirs; // 1.0.4
    
    use std::path::{Path, PathBuf};
    
    fn expand_tilde<P: AsRef<Path>>(path_user_input: P) -> Option<PathBuf> {
        let p = path_user_input.as_ref();
        if p.starts_with("~") {
            if p == Path::new("~") {
                dirs::home_dir()
            } else {
                dirs::home_dir().map(|mut h| {
                    if h == Path::new("/") {
                        // Corner case: `h` root directory;
                        // don't prepend extra `/`, just drop the tilde.
                        p.strip_prefix("~").unwrap().to_path_buf()
                    } else {
                        h.push(p.strip_prefix("~/").unwrap());
                        h
                    }
                })
            }
        } else {
            Some(p.to_path_buf())
        }
    }
    

    Примеры использования:

    #[test]
    fn test_expand_tilde() {
        // Should work on your linux box during tests, would fail in stranger
        // environments!
        let home = std::env::var("HOME").unwrap();
        let projects = PathBuf::from(format!("{}/Projects", home));
        assert_eq!(expand_tilde("~/Projects"), Some(projects));
        assert_eq!(expand_tilde("/foo/bar"), Some("/foo/bar".into()));
        assert_eq!(
            expand_tilde("~alice/projects"),
            Some("~alice/projects".into())
        );
    }
    

    Некоторые замечания:

    • Тип ввода P: AsRef<Path> имитирует то, что делает стандартная библиотека , Вот почему метод принимает все Path -подобные входные данные, такие как &str, &OsStr и &Path.
    • Path::new ничего не выделяет, оно указывает на те же байты, что и &str.
    • strip_prefix("~/").unwrap() никогда не должен потерпеть неудачу здесь, потому что мы проверили, что путь начинается с ~, а не просто ~. Единственным способом, которым это может быть, является то, что путь начинается с ~/ (из-за того, как определено starts_with).
0
ответ дан Shepmaster 22 January 2019 в 11:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: