11use crate :: routes:: token:: metadata:: { ipfs:: IpfsPath , util:: TryFromStr , FetchedMetadata } ;
2- use anyhow:: { anyhow , Result } ;
2+ use anyhow:: Result ;
33use data_url:: { forgiving_base64:: InvalidBase64 , DataUrl , DataUrlError } ;
44use serde_json:: { Error as SerdeError , Value } ;
55use std:: { error:: Error , fmt, str:: FromStr } ;
@@ -48,6 +48,8 @@ pub enum UriType {
4848 Url ( Url ) ,
4949 Ipfs ( IpfsPath ) ,
5050 Data ( String ) ,
51+ InvalidUrl ( String ) ,
52+ Json ( Value ) ,
5153}
5254
5355impl FromStr for UriType {
@@ -74,7 +76,13 @@ impl FromStr for UriType {
7476 }
7577 Ok ( Self :: Url ( url) )
7678 }
77- Err ( err) => Err ( anyhow ! ( "failed to parse as url: {s} with error {err:?}" ) ) ,
79+ Err ( err) => {
80+ // Try to parse as JSON:
81+ match serde_json:: from_str :: < Value > ( s) {
82+ Ok ( value) => Ok ( Self :: Json ( value) ) ,
83+ Err ( _) => Ok ( Self :: InvalidUrl ( err. to_string ( ) ) ) ,
84+ }
85+ }
7886 }
7987 }
8088}
@@ -286,6 +294,24 @@ mod tests {
286294 assert ! ( FetchedMetadata :: from_str( data) . is_ok( ) ) ;
287295 }
288296
297+ #[ test]
298+ fn json_uri ( ) {
299+ let data = r#"{"name": "WHO404 NFT#1","external_url":"https://who404.wtf/"}"# ;
300+
301+ assert_eq ! (
302+ UriType :: from_str( data) . unwrap( ) ,
303+ UriType :: Json ( serde_json:: from_str( data) . unwrap( ) )
304+ ) ;
305+ }
306+
307+ #[ test]
308+ fn invalid_url ( ) {
309+ assert_eq ! (
310+ UriType :: from_str( "1234.json" ) . unwrap( ) ,
311+ UriType :: InvalidUrl ( "relative URL without a base" . into( ) )
312+ ) ;
313+ }
314+
289315 #[ test]
290316 fn test_data_parsing ( ) {
291317 let data_uris = [
0 commit comments