[備忘録07]作って学ぶブラウザのしくみ / URLの構文解析の実装/ URLの分割の実装

2024/12/31に公開

parseメソッドの中みを実装していく。
rustにも正規表現を扱うregexというライブラリが存在するが、今回のプロジェクトでは外部ライブラリには頼らない。

[スキームの確認]

ユーザが入力したURLからまずはスキームを分離する。今回対応するスキームはhttpのみ。
本書で作成するブラウザの仕様としては以下となる

    pub fn parse(&mut self)-> Result<Self, String> {
        if !self.is_http() {// URLは必ずhttp://から始まらないといけない。
            return Err("Only Http scheme is supported." .to_string());
        }
    }
    pub fn is_http(&mut self)-> bool {
        if self.url.contains("http://"){
            return true;
        }
        false
    }

[ホストの取得]

URLからホストを取得する。extract_hostメソッドはメソッドが呼び出されたオブジェクト自体(&self)を引数にとり、戻り値としてはホストを文字列として返す。

use alloc::string:String;
use alloc::vec::Vec;

#[derive(Debug, Clone, PartialEq)] 
// derive属性はRustの構造体や列挙型に対して、自動的にトレイトを実装するための属性です。ここでは、Debugトレイト、CloneトレイトとPartialEqトレイトを実装しています。
pub struct Url {
    url: String,
    host: String,
    port: String,
    path: String,
    searchpart: String,
}

use alloc::string::ToString;

impl Url {
    fn type_of<T>(_: &T) -> &'static str {
        std::any::type_name::<T>()
    }
    pub fn new(url: String) -> Self { //コンストラクタ
        Self {
            url,
            host: "".to_string(),
            port: "".to_string(),
            path: "".to_string(),
            searchpart: "".to_string(),
        }
    }
    pub fn parse(&mut self)-> Result<Self, String> {
        if !self.is_http() {// URLは必ずhttp://から始まらないといけない。
            return Err("Only Http scheme is supported." .to_string());
        }
    }
    pub fn is_http(&mut self)-> bool {
        if self.url.contains("http://"){
            return true;
        }
        false
    }

    fn extract_host(&self)-> String{// 引数&selfでメソッドが呼び出されたオブジェクト自体を参照することを示している。
        let url_parts: Vec<&str> = self
            .url
            .trim_start_matches("https://") //文字列の先頭に指定した文字列がある場合、その文字列を削除する。参照https://doc.rust-lang.org/std/primitive.str.html#method.trim_start_matches
            .splitn(2, "/")// 文字列を走査して、'/'が出現するたびに分割する。分割回数は2回まで。 参照:https://doc.rust-lang.org/std/primitive.str.html#method.splitn
            .collect();// イテレータをVec<&str>というコレクションに変更して扱えるようにしている。 参照:https://zenn.dev/koko_u/scraps/5fd1002083ce62

        if let Some(index) = url_parts[0].find(':') {//標準関数findでvectorであるurl_parts[0]内のどこに":"が含まれてるかを取得している。
            url_parts[0][..index].to_string()
        }else{
            url_parts[0].to_string()
        }
    }
}

Discussion