summaryrefslogtreecommitdiff
path: root/vendor/iri-string/examples/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/iri-string/examples/parse.rs')
-rw-r--r--vendor/iri-string/examples/parse.rs159
1 files changed, 159 insertions, 0 deletions
diff --git a/vendor/iri-string/examples/parse.rs b/vendor/iri-string/examples/parse.rs
new file mode 100644
index 00000000..b447e461
--- /dev/null
+++ b/vendor/iri-string/examples/parse.rs
@@ -0,0 +1,159 @@
+//! An example to parse IRI from the CLI argument.
+
+use iri_string::types::{IriStr, RiReferenceStr, RiStr};
+
+const USAGE: &str = "\
+USAGE:
+ parse [FLAGS] [--] IRI
+
+FLAGS:
+ -h, --help Prints this help
+ -i, --iri Handle the input as an IRI (RFC 3987)
+ -u, --uri Handle the input as an URI (RFC 3986)
+
+ARGS:
+ <IRI> IRI or URI
+";
+
+fn print_help() {
+ eprintln!("{}", USAGE);
+}
+
+fn help_and_exit() -> ! {
+ print_help();
+ std::process::exit(1);
+}
+
+fn die(msg: impl std::fmt::Display) -> ! {
+ eprintln!("ERROR: {}", msg);
+ eprintln!();
+ print_help();
+ std::process::exit(1);
+}
+
+/// Syntax specification.
+#[derive(Debug, Clone, Copy)]
+enum Spec {
+ /// RFC 3986 URI.
+ Uri,
+ /// RFC 3987 IRI.
+ Iri,
+}
+
+impl Default for Spec {
+ #[inline]
+ fn default() -> Self {
+ Self::Iri
+ }
+}
+
+/// CLI options.
+#[derive(Default, Debug, Clone)]
+struct CliOpt {
+ /// IRI.
+ iri: String,
+ /// Syntax spec.
+ spec: Spec,
+}
+
+impl CliOpt {
+ fn parse() -> Self {
+ let mut args = std::env::args();
+ // Skip `argv[0]`.
+ args.next();
+
+ let mut iri = None;
+ let mut spec = None;
+
+ for arg in args.by_ref() {
+ match arg.as_str() {
+ "--iri" | "-i" => spec = Some(Spec::Iri),
+ "--uri" | "-u" => spec = Some(Spec::Uri),
+ "--help" | "-h" => help_and_exit(),
+ opt if opt.starts_with('-') => die(format_args!("Unknown option: {}", opt)),
+ _ => {
+ if iri.replace(arg).is_some() {
+ die("IRI can be specified at most once");
+ }
+ }
+ }
+ }
+
+ for arg in args {
+ if iri.replace(arg).is_some() {
+ eprintln!("ERROR: IRI can be specified at most once");
+ }
+ }
+
+ let iri = iri.unwrap_or_else(|| die("IRI should be specified"));
+ let spec = spec.unwrap_or_default();
+ Self { iri, spec }
+ }
+}
+
+fn main() {
+ let opt = CliOpt::parse();
+
+ match opt.spec {
+ Spec::Iri => parse_iri(&opt),
+ Spec::Uri => parse_uri(&opt),
+ }
+}
+
+fn parse_iri(opt: &CliOpt) {
+ let iri = parse::<iri_string::spec::IriSpec>(opt);
+ let uri = iri.encode_to_uri();
+ println!("ASCII: {:?}", uri);
+}
+
+fn parse_uri(opt: &CliOpt) {
+ let iri = parse::<iri_string::spec::UriSpec>(opt);
+ println!("ASCII: {:?}", iri);
+}
+
+fn parse<S: iri_string::spec::Spec>(opt: &CliOpt) -> &RiReferenceStr<S>
+where
+ RiStr<S>: AsRef<RiStr<iri_string::spec::IriSpec>>,
+{
+ let raw = &opt.iri.as_str();
+ let iri = match RiReferenceStr::<S>::new(raw) {
+ Ok(v) => v,
+ Err(e) => die(format_args!("Failed to parse {:?}: {}", raw, e)),
+ };
+ println!("Successfully parsed: {:?}", iri);
+
+ let absolute = iri.to_iri().ok();
+ match absolute {
+ Some(_) => println!("IRI is ablolute."),
+ None => println!("IRI is relative."),
+ }
+
+ print_components(iri);
+ if let Some(absolute) = absolute {
+ print_normalized(absolute.as_ref());
+ }
+
+ iri
+}
+
+fn print_components<S: iri_string::spec::Spec>(iri: &RiReferenceStr<S>) {
+ println!("scheme: {:?}", iri.scheme_str());
+ println!("authority: {:?}", iri.authority_str());
+ if let Some(components) = iri.authority_components() {
+ println!(" userinfo: {:?}", components.userinfo());
+ println!(" host: {:?}", components.host());
+ println!(" port: {:?}", components.port());
+ }
+ println!("path: {:?}", iri.path_str());
+ println!("query: {:?}", iri.query_str());
+ println!("fragment: {:?}", iri.fragment());
+}
+
+pub fn print_normalized(iri: &IriStr) {
+ println!("is_normalized_rfc3986: {}", iri.is_normalized_rfc3986());
+ println!(
+ "is_normalized_but_authorityless_relative_path_preserved: {}",
+ iri.is_normalized_but_authorityless_relative_path_preserved()
+ );
+ println!("normalized: {}", iri.normalize());
+}