Skip to content

Commit af20765

Browse files
committed
zulip: reduce code duplication
1 parent 483511f commit af20765

File tree

3 files changed

+180
-135
lines changed

3 files changed

+180
-135
lines changed

src/schema.rs

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

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

381424
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);
425+
groups.push(ZulipGroup(ZulipCommon {
426+
name: raw_group.common.name.clone(),
427+
includes_team_members: raw_group.common.include_team_members,
428+
members: self.expand_zulip_membership(
429+
data,
430+
&raw_group.common,
431+
|excluded| {
432+
format_err!("'{excluded}' was specifically excluded from the Zulip group '{}' but they were already not included", raw_group.common.name)
433+
},
434+
)?,
435+
}));
422436
}
423437
Ok(groups)
424438
}
@@ -432,47 +446,17 @@ impl Team {
432446
let zulip_streams = self.raw_zulip_streams();
433447

434448
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);
449+
streams.push(ZulipStream(ZulipCommon {
450+
name: raw_stream.common.name.clone(),
451+
includes_team_members: raw_stream.common.include_team_members,
452+
members: self.expand_zulip_membership(
453+
data,
454+
&raw_stream.common,
455+
|excluded| {
456+
format_err!("'{excluded}' was specifically excluded from the Zulip stream '{}' but they were already not included", raw_stream.common.name)
457+
},
458+
)?,
459+
}));
476460
}
477461
Ok(streams)
478462
}
@@ -733,7 +717,7 @@ pub(crate) struct TeamList {
733717

734718
#[derive(serde_derive::Deserialize, Debug)]
735719
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
736-
pub(crate) struct RawZulipGroup {
720+
pub(crate) struct RawZulipCommon {
737721
pub(crate) name: String,
738722
#[serde(default = "default_true")]
739723
pub(crate) include_team_members: bool,
@@ -747,20 +731,18 @@ pub(crate) struct RawZulipGroup {
747731
pub(crate) excluded_people: Vec<String>,
748732
}
749733

734+
#[derive(serde_derive::Deserialize, Debug)]
735+
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
736+
pub(crate) struct RawZulipGroup {
737+
#[serde(flatten)]
738+
pub(crate) common: RawZulipCommon,
739+
}
740+
750741
#[derive(serde_derive::Deserialize, Debug)]
751742
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
752743
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>,
744+
#[serde(flatten)]
745+
pub(crate) common: RawZulipCommon,
764746
}
765747

766748
#[derive(Debug)]
@@ -780,52 +762,49 @@ impl List {
780762
}
781763

782764
#[derive(Debug)]
783-
pub(crate) struct ZulipGroup {
765+
pub(crate) struct ZulipCommon {
784766
name: String,
785767
includes_team_members: bool,
786-
members: Vec<ZulipGroupMember>,
768+
members: Vec<ZulipMember>,
787769
}
788770

789-
impl ZulipGroup {
771+
impl ZulipCommon {
790772
pub(crate) fn name(&self) -> &str {
791773
&self.name
792774
}
793775

794-
/// Whether the group includes the members of the team its associated
776+
/// Whether the group/stream includes the members of the associated team?
795777
pub(crate) fn includes_team_members(&self) -> bool {
796778
self.includes_team_members
797779
}
798780

799-
pub(crate) fn members(&self) -> &[ZulipGroupMember] {
781+
pub(crate) fn members(&self) -> &[ZulipMember] {
800782
&self.members
801783
}
802784
}
803785

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-
811786
#[derive(Debug)]
812-
pub(crate) struct ZulipStream {
813-
name: String,
814-
members: Vec<ZulipStreamMember>,
815-
}
787+
pub(crate) struct ZulipGroup(ZulipCommon);
816788

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

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

827806
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
828-
pub(crate) enum ZulipStreamMember {
807+
pub(crate) enum ZulipMember {
829808
MemberWithId { github: String, zulip_id: u64 },
830809
JustId(u64),
831810
MemberWithoutId { github: String },

src/static_api.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use crate::data::Data;
2-
use crate::schema::{
3-
Bot, Email, Permissions, RepoPermission, TeamKind, ZulipGroupMember, ZulipStreamMember,
4-
};
2+
use crate::schema::{Bot, Email, Permissions, RepoPermission, TeamKind, ZulipMember};
53
use anyhow::{ensure, Context as _, Error};
64
use indexmap::IndexMap;
75
use log::info;
@@ -279,13 +277,13 @@ impl<'a> Generator<'a> {
279277
members: members
280278
.into_iter()
281279
.filter_map(|m| match m {
282-
ZulipGroupMember::MemberWithId { zulip_id, .. } => {
280+
ZulipMember::MemberWithId { zulip_id, .. } => {
283281
Some(v1::ZulipGroupMember::Id(zulip_id))
284282
}
285-
ZulipGroupMember::JustId(zulip_id) => {
283+
ZulipMember::JustId(zulip_id) => {
286284
Some(v1::ZulipGroupMember::Id(zulip_id))
287285
}
288-
ZulipGroupMember::MemberWithoutId { .. } => None,
286+
ZulipMember::MemberWithoutId { .. } => None,
289287
})
290288
.collect(),
291289
},
@@ -310,13 +308,13 @@ impl<'a> Generator<'a> {
310308
members: members
311309
.into_iter()
312310
.filter_map(|m| match m {
313-
ZulipStreamMember::MemberWithId { zulip_id, .. } => {
311+
ZulipMember::MemberWithId { zulip_id, .. } => {
314312
Some(v1::ZulipStreamMember::Id(zulip_id))
315313
}
316-
ZulipStreamMember::JustId(zulip_id) => {
314+
ZulipMember::JustId(zulip_id) => {
317315
Some(v1::ZulipStreamMember::Id(zulip_id))
318316
}
319-
ZulipStreamMember::MemberWithoutId { .. } => None,
317+
ZulipMember::MemberWithoutId { .. } => None,
320318
})
321319
.collect(),
322320
},

0 commit comments

Comments
 (0)