Skip to content

Commit 87644dc

Browse files
committed
zulip: reduce code duplication
1 parent ad5a1ec commit 87644dc

File tree

3 files changed

+183
-139
lines changed

3 files changed

+183
-139
lines changed

src/schema.rs

Lines changed: 96 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,51 @@ impl Team {
370370
Ok(lists)
371371
}
372372

373+
/// `on_exclude_not_included` is a function that is returned when an excluded member
374+
/// wasn't included.
375+
fn expand_zulip_membership(
376+
&self,
377+
data: &Data,
378+
common: &RawZulipCommon,
379+
on_exclude_not_included: impl Fn(&str) -> Error,
380+
) -> Result<Vec<ZulipMember>, Error> {
381+
let mut members = if common.include_team_members {
382+
self.members(data)?
383+
} else {
384+
HashSet::new()
385+
};
386+
for person in &common.extra_people {
387+
members.insert(person.as_str());
388+
}
389+
for team in &common.extra_teams {
390+
let team = data
391+
.team(team)
392+
.ok_or_else(|| format_err!("team {} is missing", team))?;
393+
members.extend(team.members(data)?);
394+
}
395+
for excluded in &common.excluded_people {
396+
if !members.remove(excluded.as_str()) {
397+
return Err(on_exclude_not_included(excluded));
398+
}
399+
}
400+
401+
let mut final_members = Vec::new();
402+
for member in members.iter() {
403+
let member = data
404+
.person(member)
405+
.ok_or_else(|| format_err!("{} does not have a person configuration", member))?;
406+
let member = match (member.github.clone(), member.zulip_id) {
407+
(github, Some(zulip_id)) => ZulipMember::MemberWithId { github, zulip_id },
408+
(github, _) => ZulipMember::MemberWithoutId { github },
409+
};
410+
final_members.push(member);
411+
}
412+
for &extra in &common.extra_zulip_ids {
413+
final_members.push(ZulipMember::JustId(extra));
414+
}
415+
Ok(final_members)
416+
}
417+
373418
pub(crate) fn raw_zulip_groups(&self) -> &[RawZulipGroup] {
374419
&self.zulip_groups
375420
}
@@ -379,46 +424,17 @@ impl Team {
379424
let zulip_groups = &self.zulip_groups;
380425

381426
for raw_group in zulip_groups {
382-
let mut group = ZulipGroup {
383-
name: raw_group.name.clone(),
384-
includes_team_members: raw_group.include_team_members,
385-
members: Vec::new(),
386-
};
387-
388-
let mut members = if raw_group.include_team_members {
389-
self.members(data)?
390-
} else {
391-
HashSet::new()
392-
};
393-
for person in &raw_group.extra_people {
394-
members.insert(person.as_str());
395-
}
396-
for team in &raw_group.extra_teams {
397-
let team = data
398-
.team(team)
399-
.ok_or_else(|| format_err!("team {} is missing", team))?;
400-
members.extend(team.members(data)?);
401-
}
402-
for excluded in &raw_group.excluded_people {
403-
if !members.remove(excluded.as_str()) {
404-
bail!("'{excluded}' was specifically excluded from the Zulip group '{}' but they were already not included", raw_group.name);
405-
}
406-
}
407-
408-
for member in members.iter() {
409-
let member = data.person(member).ok_or_else(|| {
410-
format_err!("{} does not have a person configuration", member)
411-
})?;
412-
let member = match (member.github.clone(), member.zulip_id) {
413-
(github, Some(zulip_id)) => ZulipGroupMember::MemberWithId { github, zulip_id },
414-
(github, _) => ZulipGroupMember::MemberWithoutId { github },
415-
};
416-
group.members.push(member);
417-
}
418-
for &extra in &raw_group.extra_zulip_ids {
419-
group.members.push(ZulipGroupMember::JustId(extra));
420-
}
421-
groups.push(group);
427+
groups.push(ZulipGroup(ZulipCommon {
428+
name: raw_group.common.name.clone(),
429+
includes_team_members: raw_group.common.include_team_members,
430+
members: self.expand_zulip_membership(
431+
data,
432+
&raw_group.common,
433+
|excluded| {
434+
format_err!("'{excluded}' was specifically excluded from the Zulip group '{}' but they were already not included", raw_group.common.name)
435+
},
436+
)?,
437+
}));
422438
}
423439
Ok(groups)
424440
}
@@ -432,47 +448,17 @@ impl Team {
432448
let zulip_streams = self.raw_zulip_streams();
433449

434450
for raw_stream in zulip_streams {
435-
let mut stream = ZulipStream {
436-
name: raw_stream.name.clone(),
437-
members: Vec::new(),
438-
};
439-
440-
let mut members = if raw_stream.include_team_members {
441-
self.members(data)?
442-
} else {
443-
HashSet::new()
444-
};
445-
for person in &raw_stream.extra_people {
446-
members.insert(person.as_str());
447-
}
448-
for team in &raw_stream.extra_teams {
449-
let team = data
450-
.team(team)
451-
.ok_or_else(|| format_err!("team {} is missing", team))?;
452-
members.extend(team.members(data)?);
453-
}
454-
for excluded in &raw_stream.excluded_people {
455-
if !members.remove(excluded.as_str()) {
456-
bail!("'{excluded}' was specifically excluded from the Zulip stream '{}' but they were already not included", raw_stream.name);
457-
}
458-
}
459-
460-
for member in members.iter() {
461-
let member = data.person(member).ok_or_else(|| {
462-
format_err!("{} does not have a person configuration", member)
463-
})?;
464-
let member = match (member.github.clone(), member.zulip_id) {
465-
(github, Some(zulip_id)) => {
466-
ZulipStreamMember::MemberWithId { github, zulip_id }
467-
}
468-
(github, _) => ZulipStreamMember::MemberWithoutId { github },
469-
};
470-
stream.members.push(member);
471-
}
472-
for &extra in &raw_stream.extra_zulip_ids {
473-
stream.members.push(ZulipStreamMember::JustId(extra));
474-
}
475-
streams.push(stream);
451+
streams.push(ZulipStream(ZulipCommon {
452+
name: raw_stream.common.name.clone(),
453+
includes_team_members: raw_stream.common.include_team_members,
454+
members: self.expand_zulip_membership(
455+
data,
456+
&raw_stream.common,
457+
|excluded| {
458+
format_err!("'{excluded}' was specifically excluded from the Zulip stream '{}' but they were already not included", raw_stream.common.name)
459+
},
460+
)?,
461+
}));
476462
}
477463
Ok(streams)
478464
}
@@ -733,7 +719,7 @@ pub(crate) struct TeamList {
733719

734720
#[derive(serde_derive::Deserialize, Debug)]
735721
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
736-
pub(crate) struct RawZulipGroup {
722+
pub(crate) struct RawZulipCommon {
737723
pub(crate) name: String,
738724
#[serde(default = "default_true")]
739725
pub(crate) include_team_members: bool,
@@ -747,20 +733,18 @@ pub(crate) struct RawZulipGroup {
747733
pub(crate) excluded_people: Vec<String>,
748734
}
749735

736+
#[derive(serde_derive::Deserialize, Debug)]
737+
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
738+
pub(crate) struct RawZulipGroup {
739+
#[serde(flatten)]
740+
pub(crate) common: RawZulipCommon,
741+
}
742+
750743
#[derive(serde_derive::Deserialize, Debug)]
751744
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
752745
pub(crate) struct RawZulipStream {
753-
pub(crate) name: String,
754-
#[serde(default = "default_true")]
755-
pub(crate) include_team_members: bool,
756-
#[serde(default)]
757-
pub(crate) extra_people: Vec<String>,
758-
#[serde(default)]
759-
pub(crate) extra_zulip_ids: Vec<u64>,
760-
#[serde(default)]
761-
pub(crate) extra_teams: Vec<String>,
762-
#[serde(default)]
763-
pub(crate) excluded_people: Vec<String>,
746+
#[serde(flatten)]
747+
pub(crate) common: RawZulipCommon,
764748
}
765749

766750
#[derive(Debug)]
@@ -780,52 +764,49 @@ impl List {
780764
}
781765

782766
#[derive(Debug)]
783-
pub(crate) struct ZulipGroup {
767+
pub(crate) struct ZulipCommon {
784768
name: String,
785769
includes_team_members: bool,
786-
members: Vec<ZulipGroupMember>,
770+
members: Vec<ZulipMember>,
787771
}
788772

789-
impl ZulipGroup {
773+
impl ZulipCommon {
790774
pub(crate) fn name(&self) -> &str {
791775
&self.name
792776
}
793777

794-
/// Whether the group includes the members of the team its associated
778+
/// Whether the group/stream includes the members of the associated team?
795779
pub(crate) fn includes_team_members(&self) -> bool {
796780
self.includes_team_members
797781
}
798782

799-
pub(crate) fn members(&self) -> &[ZulipGroupMember] {
783+
pub(crate) fn members(&self) -> &[ZulipMember] {
800784
&self.members
801785
}
802786
}
803787

804-
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
805-
pub(crate) enum ZulipGroupMember {
806-
MemberWithId { github: String, zulip_id: u64 },
807-
JustId(u64),
808-
MemberWithoutId { github: String },
809-
}
810-
811788
#[derive(Debug)]
812-
pub(crate) struct ZulipStream {
813-
name: String,
814-
members: Vec<ZulipStreamMember>,
815-
}
789+
pub(crate) struct ZulipGroup(ZulipCommon);
816790

817-
impl ZulipStream {
818-
pub(crate) fn name(&self) -> &str {
819-
&self.name
791+
impl std::ops::Deref for ZulipGroup {
792+
type Target = ZulipCommon;
793+
fn deref(&self) -> &Self::Target {
794+
&self.0
820795
}
796+
}
821797

822-
pub(crate) fn members(&self) -> &[ZulipStreamMember] {
823-
&self.members
798+
#[derive(Debug)]
799+
pub(crate) struct ZulipStream(ZulipCommon);
800+
801+
impl std::ops::Deref for ZulipStream {
802+
type Target = ZulipCommon;
803+
fn deref(&self) -> &Self::Target {
804+
&self.0
824805
}
825806
}
826807

827808
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
828-
pub(crate) enum ZulipStreamMember {
809+
pub(crate) enum ZulipMember {
829810
MemberWithId { github: String, zulip_id: u64 },
830811
JustId(u64),
831812
MemberWithoutId { github: String },

src/static_api.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
use crate::data::Data;
2-
use crate::schema::{
3-
Bot, Email, MergeBot, Permissions, RepoPermission, TeamKind, ZulipGroupMember,
4-
ZulipStreamMember,
5-
};
2+
use crate::schema::{Bot, Email, MergeBot, Permissions, RepoPermission, TeamKind, ZulipMember};
63
use anyhow::{ensure, Context as _, Error};
74
use indexmap::IndexMap;
85
use log::info;
@@ -287,13 +284,13 @@ impl<'a> Generator<'a> {
287284
members: members
288285
.into_iter()
289286
.filter_map(|m| match m {
290-
ZulipGroupMember::MemberWithId { zulip_id, .. } => {
287+
ZulipMember::MemberWithId { zulip_id, .. } => {
291288
Some(v1::ZulipGroupMember::Id(zulip_id))
292289
}
293-
ZulipGroupMember::JustId(zulip_id) => {
290+
ZulipMember::JustId(zulip_id) => {
294291
Some(v1::ZulipGroupMember::Id(zulip_id))
295292
}
296-
ZulipGroupMember::MemberWithoutId { .. } => None,
293+
ZulipMember::MemberWithoutId { .. } => None,
297294
})
298295
.collect(),
299296
},
@@ -318,13 +315,13 @@ impl<'a> Generator<'a> {
318315
members: members
319316
.into_iter()
320317
.filter_map(|m| match m {
321-
ZulipStreamMember::MemberWithId { zulip_id, .. } => {
318+
ZulipMember::MemberWithId { zulip_id, .. } => {
322319
Some(v1::ZulipStreamMember::Id(zulip_id))
323320
}
324-
ZulipStreamMember::JustId(zulip_id) => {
321+
ZulipMember::JustId(zulip_id) => {
325322
Some(v1::ZulipStreamMember::Id(zulip_id))
326323
}
327-
ZulipStreamMember::MemberWithoutId { .. } => None,
324+
ZulipMember::MemberWithoutId { .. } => None,
328325
})
329326
.collect(),
330327
},

0 commit comments

Comments
 (0)