PTWZYQFRWWUOE2WMQT26CKZKFSHAIJVJS3QWHJFYUFDRRTVPHSUAC SWWE2R6MVBX5CNM6X3WLXZTSRTU53PBJL7WJSFVF77XBPXDX4COAC WT3GA27PQ2AOAIGK65O3Q4DMX4AZDVNULBLRL6GF4QW6QCASUEAAC W7IUT3ZVMFH77IGKLAL7WX7IVVTGTY3FKEJ3WHMP3KI37B6NENLQC YBJRDOTCX3ZRDB5EVXJBR55FX3CADCSIGMYWNYVC2PD5W3GXR3DQC A5YBC77VWH2LXCZJOPZORQJI5ZYABSCHJWVX5HVNWPM5RABXESLQC D7A7MSIHJS3IAOLEPK52M4CZLDPLO7JB3Y62XACT2AM6UUCPQ6BAC AMPZ2BXK4IGUZO3OPBRSJ6Z4GI5K4PRFMLUGTR6AP4FKKRWQG7LQC ONRCENKTUB4JJMPXNAQQYEWDYD54TAGOLWH742GF4EH3KTHV7YLQC 23SFYK4Q5NKBPJG53PQNPWQH6UOUU2YKJEL7RLXYBRLJOJYV7AWQC OPXFZKEBDHZZLXEJ2JRDYBOJH6YIN7UZNZYHVHMWMQVDTE2ZD53QC 3QVNMRNMI63L2VOFVTMPCVPXH3J4JXLXVTIIPNOMACQCPCAPWILQC PKJCFSBMXXA2H3US47IJEB7QMIYLEKTLGWQUYEZSKCDODDQTD6HQC XSZZB47UXR6KGYFZZQFQR63X2LDKOH6TPNNBRRGHUCI5JJ4JIWVAC 3BK22XE5LPOH2EK5AMRXFXHNQNCJ54HEPYRINHJT4DA7INT32I7AC WGID4LS4EISIOXB5Y5SOFGEF5PLBJSCPFCETH2CGRTFN3NC4WGJQC ACDXXAX26ZJJFKJDGRC2GOSJY5JHQWCSTP55SYI6D6LH5UIRYUBAC I56UGW7UUKLSR4753EYRGNROZB5PD522REEOGHVAQOZZTSVRUEEQC YYKXNBFL44LLOBABLXBKOF7IFUIGIEL2SYIPLGDH6UOEY5EZZZSQC 5CYU7UT74NXJWCC36GNQGVBXH676BHBXWZQVIINRMPDEJ27SBRGAC ESMM3FELOBYIX7FUNOU37FYKRJHFU2IMX6LY6EGJTVPTBDU3SEEQC UF5NJKASGMZSZMBUKSUI67B2GIMQFX5SNNQEHHGUBNDBQ2QZZWSAC 7SSBM4UQMYVRL6L3ICYZQPSMYLZZQNMDWH6JKA3KOOSXZDJHESHQC OC6DLIZ3BKN5ZCDK77653XBR4DSTCFRXUGWDSKVGGJQNM7QZHJBAC I2AG42PAVOII4V4TWDJV5ZVNDIHKBRDT254BFQLFUIY723TW6CCQC DXAYDIMQ7BYEI3ASOHKADQWSMVJOA2ZVNEL2TDENJCJKX2U4GMWAC WW36JYLR4AILV7RHQEDJWMX74P74B7G7DRBHH3O2V5TCHRTZJWZQC SASAN2XCWDQ2VEHZ7TAQEN2R3Y7AG7JUGEFVRL4DZAGHXDFEZFRQC XZ6D3UUEHORAFR6E6NTIJAYEMNUREWPFHCR2FU7FRTHGGLUHZNVQC KEPKF3WO7ZZ2VB2DRVVTWTGPL7TCA52BMYUPHUNUJH6WO3HAT6JQC GOLHUD6RCYCO2SPULCFGWIW3ALBDODNEMUHVAKCDWYQREKWGFTLQC K5YUSV2WOLGMA75WKQWY2GRLQGPAFGVYTW3GMVTWEECXF4SXFEYAC KWTBNTO3QUUE2YADF6SYW6G6ZOKYEWRJQKIWDGZXR33S3YNDVIZQC 5MUEECMJHU44FL5RDUR3VFBIWK3H4X2L5MVJ73J37PYHZWLUKU2AC WXQBBQ2ACNPKCTDF7OTBLP342324ZIOJK42PUO2KT2IYVJ2ETCMAC 65DXFP3YLRMC7IECI5VO5ZJOQGIBYWBRJX4BK2NYVRGE4ZZDQWMQC VCNKFNUF7OWVSWC6I5D25KUZ3XZZICZ3LHWVPF2N5ZSP7LQ2JOUQC 6YZAVBWU6E5FYOI5JGEIPXGZLIKAW6LS2AOFIQWEE5DMOPPCD5PQC }pub fn load(path: &Path) -> Result<(InternalState, State), LoadError> {match std::fs::exists(path) {Ok(true) => {}Ok(false) => return Err(LoadError::DoesntExist),Err(e) => return Err(LoadError::Inaccessible(e)),}let repo = pijul::Repository::find_root(Some(path)).map_err(|_e| LoadError::NotPijulRepo)?;let internal_state = InternalState { repo };let state = get_state(&internal_state);Ok((internal_state, state))}pub fn hash_bytes(bytes: &[u8]) -> ChangeHash {let mut hasher = pijul::pristine::Hasher::default();hasher.update(bytes);hasher.finish()}/// Number of sections for nav-scrollable, containing untracked files, changed/// files, most recent log changes and a header for each of these 3 sections.pub fn nav_contents_count(repo: &State) -> usize {3 + repo.untracked_files.len() + repo.changed_files.len() + repo.log.len()
}pub(crate) fn load(path: &Path) -> Result<(InternalState, State), LoadError> {match std::fs::exists(path) {Ok(true) => {}Ok(false) => return Err(LoadError::DoesntExist),Err(e) => return Err(LoadError::Inaccessible(e)),}let repo = pijul::Repository::find_root(Some(path)).map_err(|_e| LoadError::NotPijulRepo)?;let internal_state = InternalState { repo };let state = get_state(&internal_state);Ok((internal_state, state))
fn view_repo<'a>(state: &State<'a>,repo: &'a repo::State,) -> Element<'a, Msg, Theme> {
fn view_repo<'a>(state: &State<'a>, repo: &'a Repo) -> Element<'a, Msg, Theme> {let Repo {state: repo,status_nav,} = repo;
el(scrollable(column([el(column([el(text("Untracked files:")), untracked_files()])),el(column([el(text("Changed files:")), changed_files()])),el(column([el(text("Recent changes:")), log()])),]))),
el(iced_nav_scrollable::view(status_nav,status_nav_children,status_nav_children_len,Msg::StatusNav,)),
assert!(state.repo.as_ref().unwrap().untracked_files.is_empty());assert!(state.repo.as_ref().unwrap().changed_files.is_empty());
{let repo_state = &state.repo.as_ref().unwrap().state;assert!(repo_state.untracked_files.is_empty());assert!(repo_state.changed_files.is_empty());}
assert_eq!(state.repo.as_ref().unwrap().untracked_files.len(), 1);assert!(state.repo.as_ref().unwrap().untracked_files.contains(file_to_record));assert!(state.repo.as_ref().unwrap().changed_files.is_empty());
{let repo_state = &state.repo.as_ref().unwrap().state;assert_eq!(repo_state.untracked_files.len(), 1);assert!(repo_state.untracked_files.contains(file_to_record));assert!(repo_state.changed_files.is_empty());}
assert!(state.repo.as_ref().unwrap().untracked_files.is_empty());assert_eq!(state.repo.as_ref().unwrap().changed_files.len(), 1);assert!(state.repo.as_ref().unwrap().changed_files.contains_key(file_to_record));assert_eq!(state.repo.as_ref().unwrap().changed_files.get(file_to_record).unwrap(),&BTreeSet::from_iter([repo::ChangedFileDiff::Add]));
{let repo_state = &state.repo.as_ref().unwrap().state;assert!(repo_state.untracked_files.is_empty());assert_eq!(repo_state.changed_files.len(), 1);assert!(repo_state.changed_files.contains_key(file_to_record));assert_eq!(repo_state.changed_files.get(file_to_record).unwrap(),&BTreeSet::from_iter([repo::ChangedFileDiff::Add]));}
assert_eq!(state.repo.as_ref().unwrap().untracked_files.len(), 1);assert!(state.repo.as_ref().unwrap().untracked_files.contains(file_to_record));assert!(state.repo.as_ref().unwrap().changed_files.is_empty());
{let repo_state = &state.repo.as_ref().unwrap().state;assert_eq!(repo_state.untracked_files.len(), 1);assert!(repo_state.untracked_files.contains(file_to_record));assert!(repo_state.changed_files.is_empty());}
let removed = repo.untracked_files.remove(path);debug_assert!(removed, "{:?}, path: {path}", repo.untracked_files);repo.changed_files
let removed = repo_state.untracked_files.remove(path);debug_assert!(removed,"{:?}, path: {path}",repo_state.untracked_files);repo_state.changed_files
let ix = cmp::min(*ix, repo.untracked_files.len() - 1);Some(cursor::untracked_file_selection(repo, ix, &mut state.files))
let ix = cmp::min(*ix, repo_state.untracked_files.len() - 1);Some(cursor::untracked_file_selection(repo_state,ix,&mut state.files,))
repo.untracked_files.insert(path.clone());
repo_state.untracked_files.insert(path.clone());// Re-initialize navlet contents_count = repo::nav_contents_count(repo_state);let (new_status_nav, status_nav_task) =iced_nav_scrollable::init(contents_count, HashSet::default());*status_nav = new_status_nav;
let ix = cmp::min(*ix, repo.changed_files.len() - 1);Some(cursor::changed_file_selection(repo, ix, &mut state.files))
let ix = cmp::min(*ix, repo_state.changed_files.len() - 1);Some(cursor::changed_file_selection(repo_state,ix,&mut state.files,))
let nav_subs = match state.cursor.selection.as_ref() {
let status_nav_sub = if state.repo.is_some() {iced_nav_scrollable::subs().map(|msg| Msg::View(app::Msg::StatusNav(msg)))} else {Subscription::none()};let diff_nav_subs = match state.cursor.selection.as_ref() {
debug_assert_eq!(nav.section_heights.len(), children_len, "The `NavScrollable` was most likely initialized with a count different from the number of actual children given to the the view function. Count is {}, but got {} children", nav.section_heights.len(), children_len);
debug_assert_eq!(nav.section_heights.len(), children_len, "The `NavScrollable` was most likely initialized with a count different from the number of actual children given to the the view function. Actual number is {}, but got {} children_len arg", nav.section_heights.len(), children_len);