public static function fromString(string $string): self
    {
        try {
            $data = Uri\parse(trim($string));
        } catch (\Exception $e) {
            throw new InvalidArgumentException;
        }

        return new self(
            $data['scheme'] ? new Scheme($data['scheme']) : new NullScheme,
            new Authority(
                new UserInformation(
                    $data['user'] ? new User($data['user']) : new NullUser,
                    $data['pass'] ? new Password($data['pass']) : new NullPassword
                ),
                $data['host'] ? new Host($data['host']) : new NullHost,
                $data['port'] ? new Port((int) $data['port']) : new NullPort
            ),
            $data['path'] && !empty($data['path']) ? new Path($data['path']) : new NullPath,
            $data['query'] ? Query::fromString($data['query']) : new NullQuery,
            $data['fragment'] ? new Fragment($data['fragment']) : new NullFragment
        );
    }