Closed22
enum to iter を考える【Rust】
enum を作って、それを loop で回して、それぞれのタイプについて処理をする、ということをしようと思った
が、enum と iter, vec の変換をする機構は rust は標準では持っていないらしい
が、enum と iter, vec の変換をする機構は rust は標準では持っていないらしい
外部の crate を使えばできるっぽいけど、それは果たして rust っぽいのか
- 文字列タイプ(例: aから始まる, bから始まる)
- 文字列(例: boot)
文字列に対して、文字列タイプに応じた処理をやっていく、みたいなことはできるけど、
文字列がどの文字列タイプにマッチしてるのか確認してから、処理する、
みたいな流れにすれば、タイプで loop させなくてもできそう
例が雑なのは、あとでできればコードサンプル載せたい
文字列がどの文字列タイプにマッチしてるのか確認してから、処理する、
のためには、どっちみち文字列タイプをループさせる必要があるから、ダメそう
#[derive(Debug)]
enum DiscordStringType {
Channel,
Role,
Emoji,
Mention,
}
impl DiscordStringType {
fn to_regex(&self) -> Regex {
match self {
DiscordStringType::Channel => Regex::new(r"<#[0-9]+?>").unwrap(),
DiscordStringType::Role => Regex::new(r"<@&[0-9]+?>").unwrap(),
DiscordStringType::Emoji => Regex::new(r"<:(.+?):[0-9]+?>").unwrap(),
DiscordStringType::Mention => Regex::new(r"<@![0-9]+?>").unwrap(),
}
}
fn to_convert_type(&self) -> ConvertType {
match self {
DiscordStringType::Channel => ConvertType::Empty,
DiscordStringType::Role => ConvertType::Empty,
DiscordStringType::Emoji => ConvertType::MatchString,
DiscordStringType::Mention => ConvertType::Empty,
}
}
// TODO: このままだと変換に漏れがあるので修正したい
fn values() -> Vec<DiscordStringType> {
vec![
DiscordStringType::Channel,
DiscordStringType::Role,
DiscordStringType::Emoji,
DiscordStringType::Mention,
]
}
}
enum ConvertType {
Empty,
MatchString,
}
impl ConvertType {
fn convert(&self, regex: &Regex, str: &str) -> String {
match self {
ConvertType::Empty => regex.replace_all(str, "").to_string(),
ConvertType::MatchString => regex.captures_iter(str)
.collect::<Vec<_>>()
.iter()
.fold(str.to_string(), |acc, cap| {
acc.replace(&cap[0], &cap[1])
}).to_string(),
}
}
}
fn convert_discord_string(str: &str) -> String {
let mut converted = str.to_string();
for type_ in DiscordStringType::values() {
let re = type_.to_regex();
let convert_type = type_.to_convert_type();
converted = convert_type.convert(
&re,
&converted,
);
}
converted
}
enum DiscordStringType {
Channel,
Role,
Emoji,
Mention,
}
impl DiscordStringType {
// TODO: このままだと変換に漏れがあるので修正したい
fn values() -> Vec<DiscordStringType> {
vec![
DiscordStringType::Channel,
DiscordStringType::Role,
DiscordStringType::Emoji,
DiscordStringType::Mention,
]
}
}
なんとかならんもんか
enum -> vec した場合、型の厳格性が失われるからあんまりやりたくないとかあるのかな
str -> enum を regex の pattern match で変換できれば良き。
そんなことはできるんだろうか
かけなくはなさそうだけど書き方はわからない
fn str_to_discord_string_type(str: &str) -> Option<DiscordStringType> {
match str {
Regex::new(r"<#[0-9]+?>") => Some(DiscordStringType::Channel),
Regex::new(r"<@&[0-9]+?>") => Some(DiscordStringType::Role),
Regex::new(r"<:(.+?):[0-9]+?>") => Some(DiscordStringType::Emoji),
Regex::new(r"<@![0-9]+?>") => Some(DiscordStringType::Mention),
_ => None,
}
}
こういうかんじに書きたいけどかけない。ぴえん
この書き方するなら、if で一つづつ書いても変わらなさそう
enum DiscordStringType {
Channel,
Role,
Emoji,
Mention,
}
impl DiscordStringType {
fn to_regex(&self) -> Regex {
match self {
DiscordStringType::Channel => Regex::new(r"<#[0-9]+?>").unwrap(),
DiscordStringType::Role => Regex::new(r"<@&[0-9]+?>").unwrap(),
DiscordStringType::Emoji => Regex::new(r"<:(.+?):[0-9]+?>").unwrap(),
DiscordStringType::Mention => Regex::new(r"<@![0-9]+?>").unwrap(),
}
}
fn to_convert_type(&self) -> ConvertType {
match self {
DiscordStringType::Channel => ConvertType::Empty,
DiscordStringType::Role => ConvertType::Empty,
DiscordStringType::Emoji => ConvertType::MatchString,
DiscordStringType::Mention => ConvertType::Empty,
}
}
}
enum ConvertType {
Empty,
MatchString,
}
impl ConvertType {
fn convert(&self, regex: &Regex, str: &str) -> String {
match self {
ConvertType::Empty => regex.replace_all(str, "").to_string(),
ConvertType::MatchString => regex
.captures_iter(str)
.collect::<Vec<_>>()
.iter()
.fold(str.to_string(), |acc, cap| acc.replace(&cap[0], &cap[1])),
}
}
}
fn convert_discord_string(str: &str) -> String {
let (re, convert_type) = if let Some(type_) = str_to_discord_string_type(str) {
(type_.to_regex(), type_.to_convert_type())
} else {
return str.to_string();
};
convert_discord_string(&convert_type.convert(&re, str))
}
fn str_to_discord_string_type(str: &str) -> Option<DiscordStringType> {
if (Regex::new(r"<#[0-9]+?>").unwrap()).is_match(str) {
Some(DiscordStringType::Channel)
} else if (Regex::new(r"<@&[0-9]+?>").unwrap()).is_match(str) {
Some(DiscordStringType::Role)
} else if (Regex::new(r"<:(.+?):[0-9]+?>").unwrap()).is_match(str) {
Some(DiscordStringType::Emoji)
} else if (Regex::new(r"<@![0-9]+?>").unwrap()).is_match(str) {
Some(DiscordStringType::Mention)
} else {
None
}
}
なんか遠回しな感じ…
ぐぬぬぬ
enum DiscordStringType {
Channel,
Role,
Emoji,
Mention,
}
impl DiscordStringType {
fn to_regex(&self) -> Regex {
match self {
DiscordStringType::Channel => Regex::new(r"<#[0-9]+?>").unwrap(),
DiscordStringType::Role => Regex::new(r"<@&[0-9]+?>").unwrap(),
DiscordStringType::Emoji => Regex::new(r"<:(.+?):[0-9]+?>").unwrap(),
DiscordStringType::Mention => Regex::new(r"<@![0-9]+?>").unwrap(),
}
}
fn to_convert_type(&self) -> ConvertType {
match self {
DiscordStringType::Channel => ConvertType::Empty,
DiscordStringType::Role => ConvertType::Empty,
DiscordStringType::Emoji => ConvertType::MatchString,
DiscordStringType::Mention => ConvertType::Empty,
}
}
fn from_str(s: &str) -> Option<DiscordStringType> {
let type_ = DiscordStringType::Channel;
if type_.to_regex().is_match(s) {
return Some(type_);
}
let type_ = DiscordStringType::Role;
if type_.to_regex().is_match(s) {
return Some(type_);
}
let type_ = DiscordStringType::Emoji;
if type_.to_regex().is_match(s) {
return Some(type_);
}
let type_ = DiscordStringType::Mention;
if type_.to_regex().is_match(s) {
return Some(type_);
}
None
}
}
enum ConvertType {
Empty,
MatchString,
}
impl ConvertType {
fn convert(&self, regex: &Regex, str: &str) -> String {
match self {
ConvertType::Empty => regex.replace_all(str, "").to_string(),
ConvertType::MatchString => regex
.captures_iter(str)
.collect::<Vec<_>>()
.iter()
.fold(str.to_string(), |acc, cap| acc.replace(&cap[0], &cap[1])),
}
}
}
fn convert_discord_string(str: &str) -> String {
let (re, convert_type) = if let Some(type_) = DiscordStringType::from_str(str) {
(type_.to_regex(), type_.to_convert_type())
} else {
return str.to_string();
};
convert_discord_string(&convert_type.convert(&re, str))
}
やっぱり、from_str
の条件分岐を書き忘れるとダメそうなのが気になる
どないしょばれいしょ
無限に時間が溶けるぴえん
無限に時間が溶けるぴえん
一旦 close
また同じことやりたくなった
enum 回すのがいいのかも?
このスクラップは2022/09/21にクローズされました