#[derive(Hash,Eq,PartialEq)]
pub struct RobloxAssetId(pub u64);
#[derive(Debug)]
#[allow(dead_code)]
pub struct StringWithError{
	string:String,
	error:RobloxAssetIdParseErr,
}
impl std::fmt::Display for StringWithError{
	fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
		write!(f,"{self:?}")
	}
}
impl std::error::Error for StringWithError{}
impl StringWithError{
	const fn new(
		string:String,
		error:RobloxAssetIdParseErr,
	)->Self{
		Self{string,error}
	}
}
#[derive(Debug)]
pub enum RobloxAssetIdParseErr{
	Url(url::ParseError),
	UnknownScheme,
	ParseInt(std::num::ParseIntError),
	MissingAssetId,
}
impl std::str::FromStr for RobloxAssetId{
	type Err=StringWithError;
	fn from_str(s:&str)->Result<Self,Self::Err>{
		let url=url::Url::parse(s).map_err(|e|StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::Url(e)))?;
		let parsed_asset_id=match url.scheme(){
			"rbxassetid"=>url.domain().ok_or_else(||StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::MissingAssetId))?.parse(),
			"http"|"https"=>{
				let (_,asset_id)=url.query_pairs()
				.find(|(id,_)|match id.as_ref(){
					"ID"|"id"|"Id"|"iD"=>true,
					_=>false,
				}).ok_or_else(||StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::MissingAssetId))?;
				asset_id.parse()
			},
			_=>Err(StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::UnknownScheme))?,
		};
		Ok(Self(parsed_asset_id.map_err(|e|StringWithError::new(s.to_owned(),RobloxAssetIdParseErr::ParseInt(e)))?))
	}
}
