feat: Add an example about how to create a vote with comment
This commit is contained in:
parent
bebb35e686
commit
a71a966989
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
use heromodels::db::{Collection, Db};
|
use heromodels::db::{Collection, Db};
|
||||||
use heromodels::models::governance::{Proposal, ProposalStatus, VoteEventStatus};
|
use heromodels::models::governance::{Ballot, Proposal, ProposalStatus, VoteEventStatus};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Governance Proposal Model Example\n");
|
println!("Governance Proposal Model Example\n");
|
||||||
@ -99,6 +99,46 @@ fn main() {
|
|||||||
}
|
}
|
||||||
println!("");
|
println!("");
|
||||||
|
|
||||||
|
// Example of voting with comments using the cast_vote_with_comment method
|
||||||
|
println!("Adding votes with comments...");
|
||||||
|
|
||||||
|
// User 7 votes for 'Approve Allocation' with a comment
|
||||||
|
proposal = proposal.cast_vote_with_comment(
|
||||||
|
Some(110), // ballot_id
|
||||||
|
7, // user_id
|
||||||
|
1, // chosen_option_id (Approve Allocation)
|
||||||
|
80, // shares
|
||||||
|
"I strongly support this proposal because it aligns with our community values."
|
||||||
|
);
|
||||||
|
|
||||||
|
// User 8 votes for 'Reject Allocation' with a comment
|
||||||
|
proposal = proposal.cast_vote_with_comment(
|
||||||
|
Some(111), // ballot_id
|
||||||
|
8, // user_id
|
||||||
|
2, // chosen_option_id (Reject Allocation)
|
||||||
|
60, // shares
|
||||||
|
"I have concerns about the allocation priorities."
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("\nBallots with Comments:");
|
||||||
|
for ballot in &proposal.ballots {
|
||||||
|
if let Some(comment) = &ballot.comment {
|
||||||
|
println!(
|
||||||
|
"- Ballot ID: {}, User ID: {}, Option ID: {}, Shares: {}",
|
||||||
|
ballot.base_data.id, ballot.user_id, ballot.vote_option_id, ballot.shares_count
|
||||||
|
);
|
||||||
|
println!(" Comment: \"{}\"", comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("\nUpdated Vote Counts After Comments:");
|
||||||
|
for option in &proposal.options {
|
||||||
|
println!(
|
||||||
|
"- Option ID: {}, Text: '{}', Votes: {}",
|
||||||
|
option.id, option.text, option.count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Change proposal status
|
// Change proposal status
|
||||||
proposal = proposal.change_proposal_status(ProposalStatus::Active);
|
proposal = proposal.change_proposal_status(ProposalStatus::Active);
|
||||||
println!("Changed Proposal Status to: {:?}", proposal.status);
|
println!("Changed Proposal Status to: {:?}", proposal.status);
|
||||||
@ -176,6 +216,50 @@ fn main() {
|
|||||||
// User 40 (ineligible) tries to vote with auto-generated ballot ID
|
// User 40 (ineligible) tries to vote with auto-generated ballot ID
|
||||||
private_proposal = private_proposal.cast_vote(None, 40, 1, 50);
|
private_proposal = private_proposal.cast_vote(None, 40, 1, 50);
|
||||||
|
|
||||||
|
// Example of voting with comments on a private proposal
|
||||||
|
println!("\nAdding votes with comments to private proposal...");
|
||||||
|
|
||||||
|
// User 20 (eligible) votes with a comment
|
||||||
|
private_proposal = private_proposal.cast_vote_with_comment(
|
||||||
|
Some(202), // ballot_id
|
||||||
|
20, // user_id (eligible)
|
||||||
|
1, // chosen_option_id
|
||||||
|
75, // shares
|
||||||
|
"I support this restructuring plan with some reservations."
|
||||||
|
);
|
||||||
|
|
||||||
|
// User 30 (eligible) votes with a comment
|
||||||
|
private_proposal = private_proposal.cast_vote_with_comment(
|
||||||
|
Some(203), // ballot_id
|
||||||
|
30, // user_id (eligible)
|
||||||
|
2, // chosen_option_id
|
||||||
|
90, // shares
|
||||||
|
"I believe we should reconsider the timing of these changes."
|
||||||
|
);
|
||||||
|
|
||||||
|
// User 40 (ineligible) tries to vote with a comment
|
||||||
|
private_proposal = private_proposal.cast_vote_with_comment(
|
||||||
|
Some(204), // ballot_id
|
||||||
|
40, // user_id (ineligible)
|
||||||
|
1, // chosen_option_id
|
||||||
|
50, // shares
|
||||||
|
"This restructuring seems unnecessary."
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("Eligible users 20 and 30 added votes with comments.");
|
||||||
|
println!("Ineligible user 40 attempted to vote with a comment (should be rejected).");
|
||||||
|
|
||||||
|
println!("\nPrivate Proposal Ballots with Comments:");
|
||||||
|
for ballot in &private_proposal.ballots {
|
||||||
|
if let Some(comment) = &ballot.comment {
|
||||||
|
println!(
|
||||||
|
"- Ballot ID: {}, User ID: {}, Option ID: {}, Shares: {}",
|
||||||
|
ballot.base_data.id, ballot.user_id, ballot.vote_option_id, ballot.shares_count
|
||||||
|
);
|
||||||
|
println!(" Comment: \"{}\"", comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
println!("Private Proposal Vote Counts:");
|
println!("Private Proposal Vote Counts:");
|
||||||
for option in &private_proposal.options {
|
for option in &private_proposal.options {
|
||||||
println!(
|
println!(
|
||||||
|
@ -73,6 +73,7 @@ pub struct Ballot {
|
|||||||
pub user_id: u32, // The ID of the user who cast this ballot
|
pub user_id: u32, // The ID of the user who cast this ballot
|
||||||
pub vote_option_id: u8, // The 'id' of the VoteOption chosen
|
pub vote_option_id: u8, // The 'id' of the VoteOption chosen
|
||||||
pub shares_count: i64, // Number of shares/tokens/voting power
|
pub shares_count: i64, // Number of shares/tokens/voting power
|
||||||
|
pub comment: Option<String>, // Optional comment from the voter
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ballot {
|
impl Ballot {
|
||||||
@ -94,6 +95,7 @@ impl Ballot {
|
|||||||
user_id,
|
user_id,
|
||||||
vote_option_id,
|
vote_option_id,
|
||||||
shares_count,
|
shares_count,
|
||||||
|
comment: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,4 +231,65 @@ impl Proposal {
|
|||||||
self.vote_status = new_status;
|
self.vote_status = new_status;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cast a vote with a comment
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `ballot_id` - Optional ID for the ballot (use None for auto-generated ID)
|
||||||
|
/// * `user_id` - ID of the user who is casting the vote
|
||||||
|
/// * `chosen_option_id` - ID of the vote option chosen
|
||||||
|
/// * `shares` - Number of shares/tokens/voting power
|
||||||
|
/// * `comment` - Comment from the voter explaining their vote
|
||||||
|
pub fn cast_vote_with_comment(
|
||||||
|
mut self,
|
||||||
|
ballot_id: Option<u32>,
|
||||||
|
user_id: u32,
|
||||||
|
chosen_option_id: u8,
|
||||||
|
shares: i64,
|
||||||
|
comment: impl ToString,
|
||||||
|
) -> Self {
|
||||||
|
// First check if voting is open
|
||||||
|
if self.vote_status != VoteEventStatus::Open {
|
||||||
|
eprintln!("Voting is not open for proposal '{}'", self.title);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the option exists
|
||||||
|
if !self.options.iter().any(|opt| opt.id == chosen_option_id) {
|
||||||
|
eprintln!(
|
||||||
|
"Chosen option ID {} does not exist for proposal '{}'",
|
||||||
|
chosen_option_id, self.title
|
||||||
|
);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check eligibility for private proposals
|
||||||
|
if let Some(group) = &self.private_group {
|
||||||
|
if !group.contains(&user_id) {
|
||||||
|
eprintln!(
|
||||||
|
"User {} is not eligible to vote on proposal '{}'",
|
||||||
|
user_id, self.title
|
||||||
|
);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new ballot with the comment
|
||||||
|
let mut new_ballot = Ballot::new(ballot_id, user_id, chosen_option_id, shares);
|
||||||
|
new_ballot.comment = Some(comment.to_string());
|
||||||
|
|
||||||
|
// Add the ballot to the proposal
|
||||||
|
self.ballots.push(new_ballot);
|
||||||
|
|
||||||
|
// Update the vote count for the chosen option
|
||||||
|
if let Some(option) = self
|
||||||
|
.options
|
||||||
|
.iter_mut()
|
||||||
|
.find(|opt| opt.id == chosen_option_id)
|
||||||
|
{
|
||||||
|
option.count += shares;
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user