blob: d3ff38886bf95e3eaf419f95dd3da45cd1444dd0 [file] [log] [blame]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
/// Result of polling a path.
///
/// If it's a file, the result is combined from the file's "last modification"
/// time and size, so that a change to either can be noticed as a change.
///
/// If the path is not a file, [fileExists] return `false`.
extension type PollResult._(int _value) {
/// A [PollResult] with [fileExists] `false`.
factory PollResult.notAFile() => PollResult._(0);
static Future<PollResult> poll(String path) async {
final stat = await FileStat.stat(path);
if (stat.type != FileSystemEntityType.file) return PollResult.notAFile();
// Construct the poll result from the "last modified" time and size.
// It should be very likely to change if either changes. Both are 64 bit
// ints with the interesting bits in the low bits. Swap the 32 bit sections
// of `microseconds` so the interesting bits don't clash, then XOR them.
var microseconds = stat.modified.microsecondsSinceEpoch;
microseconds = microseconds << 32 | microseconds >>> 32;
return PollResult._(microseconds ^ stat.size);
}
/// Whether the path exists and is a file.
bool get fileExists => _value != 0;
}