1use crate::{get_compose_filename, ComposeYaml, Formats, Verbosity};
2use colored::Colorize;
3use regex::Regex;
4use serde_yaml::Mapping;
5use std::cmp::min;
6use std::vec::IntoIter;
7use std::{fs, process};
8
9pub fn unwrap_filter_tag(filter: Option<&str>) -> Option<&str> {
12 filter.as_ref().map(|f| {
13 if let Some(val) = f.strip_prefix("tag=") {
14 val
15 } else {
16 eprintln!(
17 "{}: wrong filter '{}', only '{}' filter supported",
18 "ERROR".red(),
19 f.yellow(),
20 "tag=".yellow()
21 );
22 process::exit(2);
23 }
24 })
25}
26
27pub fn unwrap_filter_regex(filter: Option<&str>) -> Option<(Regex, bool)> {
55 filter.as_ref().map(|f| {
56 if let Some(val) = f.strip_prefix("regex=") {
57 let regex = Regex::new(val).unwrap_or_else(|e| {
58 invalid_regex_exit(e, val);
59 });
60 return (regex, true);
61 }
62 if let Some(val) = f.strip_prefix("regex!=") {
63 let regex = Regex::new(val).unwrap_or_else(|e| {
64 invalid_regex_exit(e, val);
65 });
66 return (regex, false);
67 }
68 eprintln!(
69 "{}: wrong filter '{}', only '{}' or '{}' filters are supported",
70 "ERROR".red(),
71 f.yellow(),
72 "regex=".yellow(),
73 "regex!=".yellow()
74 );
75 process::exit(2);
76 })
77}
78
79fn invalid_regex_exit(e: regex::Error, val: &str) -> ! {
80 eprintln!(
81 "{}: invalid regex expression '{}' in filter - {}",
82 "ERROR".red(),
83 val.yellow(),
84 e
85 );
86 process::exit(2);
87}
88
89pub fn print_names(iter: IntoIter<&str>, pretty: Formats) {
90 match pretty {
91 Formats::Full => iter.for_each(|service| println!("{}", service)),
92 Formats::Oneline => println!("{}", iter.collect::<Vec<&str>>().join(" ")),
93 }
94}
95
96pub fn get_service<'a>(compose: &'a ComposeYaml, service_name: &str) -> &'a Mapping {
97 let service = compose.get_service(service_name);
98 match service {
99 None => {
100 eprintln!("{}: No such service found: {}", "ERROR".red(), service_name);
101 process::exit(16);
102 }
103 Some(serv) => serv,
104 }
105}
106
107pub fn get_yml_content(filename: Option<&str>, verbosity: Verbosity) -> String {
108 let filename = get_compose_filename(filename, verbosity).unwrap_or_else(|err| {
109 eprintln!("{}: {}", "ERROR".red(), err);
110 if err.contains("no such file or directory") {
111 process::exit(1);
112 }
113 process::exit(10);
114 });
115 fs::read_to_string(filename).unwrap_or_else(|err| {
116 eprintln!("{}: reading compose file: {}", "ERROR".red(), err);
117 process::exit(11);
118 })
119}
120
121pub fn get_slug(input: &str) -> String {
133 let text = input.trim();
134 let text = text.to_lowercase();
135 let len = min(text.len(), 63);
136 let mut result = String::with_capacity(len);
137
138 for c in text.chars() {
139 if result.len() >= len {
140 break;
141 }
142 if c.is_ascii_alphanumeric() || c == '.' {
143 result.push(c);
144 } else {
145 result.push('-');
146 }
147 }
148 result
149}